<?xml version="1.0" encoding="utf-8"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>sglavoie.com – Tag: Best Practices</title><link>https://www.sglavoie.com/tags/best-practices/</link><description>Posts and writings by Sébastien Lavoie. Customization setups and articles on productivity for developers who like minimalism.</description><language>en</language><atom:link href="https://www.sglavoie.com/tags/best-practices/feed.xml" rel="self" type="application/rss+xml"/><lastBuildDate>Sat, 24 Aug 2024 14:55:00 -0600</lastBuildDate><item><title>Book summary: 100 Go Mistakes and How to Avoid Them</title><link>https://www.sglavoie.com/posts/book-summary-100-go-mistakes-and-how-to-avoid-them/</link><description>100 Go Mistakes and How to Avoid Them is a truly insightful book by Teiva Harsanyi that covers common mistakes made by Go developers. This summary provides a high-level overview of the book’s content.</description><content:encoded>&lt;hr&gt;
&lt;h2 id="go-simple-to-learn-but-hard-to-master"&gt;Go: Simple to learn but hard to master&lt;/h2&gt;
&lt;h3 id="go-outline"&gt;Go outline&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Go does not have:
&lt;ul&gt;
&lt;li&gt;Type inheritance;&lt;/li&gt;
&lt;li&gt;Macros;&lt;/li&gt;
&lt;li&gt;Partial functions;&lt;/li&gt;
&lt;li&gt;Support for lazy variable evaluation;&lt;/li&gt;
&lt;li&gt;Support for immutability;&lt;/li&gt;
&lt;li&gt;Operator overloading;&lt;/li&gt;
&lt;li&gt;Pattern matching;&lt;/li&gt;
&lt;li&gt;&amp;hellip;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Go is:
&lt;ul&gt;
&lt;li&gt;Stable;&lt;/li&gt;
&lt;li&gt;Expressive;&lt;/li&gt;
&lt;li&gt;Fast to compile;&lt;/li&gt;
&lt;li&gt;Safe (type-safety);&lt;/li&gt;
&lt;li&gt;Simple;&lt;/li&gt;
&lt;li&gt;Excellent for concurrent programming (goroutines, channels).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="simple-doesnt-mean-easy"&gt;Simple doesn&amp;rsquo;t mean easy&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Concurrency in Go may be &lt;em&gt;simpler&lt;/em&gt; than in other languages, but it is still hard to get right, as per &lt;a href="https://engineering.purdue.edu/WukLab/GoStudy-ASPLOS19.pdf"&gt;this study&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="100-go-mistakes"&gt;100 Go mistakes&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Learning from mistakes is efficient.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&amp;ldquo;the best time for brain growth is when we&amp;rsquo;re facing mistakes&amp;rdquo;&lt;/em&gt; (&lt;a href="https://pubmed.ncbi.nlm.nih.gov/22042726/"&gt;source&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&amp;ldquo;we can remember not only the error but also the context surrounding the mistake&amp;rdquo;&lt;/em&gt; (&lt;a href="https://pubmed.ncbi.nlm.nih.gov/27648988/"&gt;source&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;Categories of mistakes
&lt;ul&gt;
&lt;li&gt;Bugs
&lt;ul&gt;
&lt;li&gt;Bugs are very costly (&lt;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"&gt;source&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;Bugs can be very dangerous (e.g., in the case of a radiation therapy machine).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Needless complexity
&lt;ul&gt;
&lt;li&gt;Don&amp;rsquo;t over-complicate things.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Weaker readability
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&amp;ldquo;the ratio of time spent reading versus writing is well over 10 to 1&amp;rdquo;&lt;/em&gt; (&lt;a href="https://www.oreilly.com/library/view/clean-code-a/9780136083238/"&gt;source&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;Nested code.&lt;/li&gt;
&lt;li&gt;Data type representation.&lt;/li&gt;
&lt;li&gt;Not using named result parameters.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Suboptimal or unidiomatic organization
&lt;ul&gt;
&lt;li&gt;Utility packages.&lt;/li&gt;
&lt;li&gt;Init functions.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Lack of API convenience
&lt;ul&gt;
&lt;li&gt;Overusing &lt;code&gt;any&lt;/code&gt; types.&lt;/li&gt;
&lt;li&gt;Wrong creational pattern.&lt;/li&gt;
&lt;li&gt;Blindly applying OOP principles.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Under-optimized code
&lt;ul&gt;
&lt;li&gt;Lack of fundamental knowledge.&lt;/li&gt;
&lt;li&gt;Impacted performance.&lt;/li&gt;
&lt;li&gt;Floating-point accuracy.&lt;/li&gt;
&lt;li&gt;Poorly parallelized execution.&lt;/li&gt;
&lt;li&gt;Not knowing how to reduce allocations.&lt;/li&gt;
&lt;li&gt;Data alignment.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Lack of productivity
&lt;ul&gt;
&lt;li&gt;Know how to write efficient tests.&lt;/li&gt;
&lt;li&gt;Use the standard library.&lt;/li&gt;
&lt;li&gt;Use profilers and linters.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="code-and-project-organization"&gt;Code and project organization&lt;/h2&gt;
&lt;h3 id="1---unintended-variable-shadowing"&gt;1 - Unintended variable shadowing&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;A variable name declared in a block can be re-declared in a nested block (&lt;em&gt;variable shadowing&lt;/em&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// client is shadowed&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Client&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// will always be nil&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;tracing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;createClientWithTracing&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;createDefaultClient&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Solutions
&lt;ul&gt;
&lt;li&gt;Use a temporary variable name in the inner scope.&lt;/li&gt;
&lt;li&gt;Use the &lt;code&gt;=&lt;/code&gt; operator instead of &lt;code&gt;:=&lt;/code&gt; in the inner scope. Leads to a single assignment. Error handling can be handled in the outer scope (&lt;code&gt;client, err = ...&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Be caution with reusing &lt;code&gt;err&lt;/code&gt; as well.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="2---unnecessary-nested-code"&gt;2 - Unnecessary nested code&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Put the happy path first and return early on all edge cases and errors.&lt;/li&gt;
&lt;li&gt;Instead of using &lt;code&gt;else&lt;/code&gt; blocks, use early returns.&lt;/li&gt;
&lt;li&gt;Instead of checking for an happy path, check for the error path and return where possible.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="3---misusing-init-functions"&gt;3 - Misusing init functions&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Refresher on &lt;code&gt;init&lt;/code&gt; functions
&lt;ul&gt;
&lt;li&gt;An init function is a special function that is executed before the main function. It takes no arguments and returns no values.&lt;/li&gt;
&lt;li&gt;Variables are initialized, the &lt;code&gt;init&lt;/code&gt; function is called, and then the &lt;code&gt;main&lt;/code&gt; function is called.&lt;/li&gt;
&lt;li&gt;Imported packages are initialized before the &lt;code&gt;main&lt;/code&gt; function is called and before the &lt;code&gt;init&lt;/code&gt; function in the main package is called because the main package depends on the imported packages.&lt;/li&gt;
&lt;li&gt;Packages can define multiple &lt;code&gt;init&lt;/code&gt; functions, in which case they are executed in alphabetical order based on the source code file name. Hence, we should not depend on the order of execution of &lt;code&gt;init&lt;/code&gt; functions as file names can change.&lt;/li&gt;
&lt;li&gt;The same source file can define multiple &lt;code&gt;init&lt;/code&gt; functions, in which case they are executed in the order they are defined in the file.&lt;/li&gt;
&lt;li&gt;The underscore operator (&lt;code&gt;_&lt;/code&gt;) can be used to import a package without using it. This is useful to execute the &lt;code&gt;init&lt;/code&gt; function of a package without using the package itself.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;init&lt;/code&gt; functions cannot be invoked explicitly.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;When to use &lt;code&gt;init&lt;/code&gt; functions
&lt;ul&gt;
&lt;li&gt;They should not be used to initialize variables, as error handling is limited (they don&amp;rsquo;t return errors, one must &lt;code&gt;panic&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;When testing a package, the &lt;code&gt;init&lt;/code&gt; function is executed before the tests are run.&lt;/li&gt;
&lt;li&gt;If side effects are achieved via variables, these become global variables, which pollute the global namespace. Any function in the package can access these variables, which can lead to unexpected behavior. Unit tests depending on such functions will be harder to write.&lt;/li&gt;
&lt;li&gt;The responsibility of error handling should be left up to the caller.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;They can be helpful to define static configurations&lt;/em&gt;, as is done in &lt;a href="https://cs.opensource.google/go/x/website/&amp;#43;/e0d934b4:blog/blog.go;l=32"&gt;the &lt;code&gt;init&lt;/code&gt; function of the Go blog&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="4---overusing-getters-and-setters"&gt;4 - Overusing getters and setters&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Go has no support for automatic getters and setters, and it is idiomatic to use direct access to fields.&lt;/li&gt;
&lt;li&gt;When the use case justifies it, a getter should be named &lt;code&gt;FieldName&lt;/code&gt; (not &lt;code&gt;GetFieldName&lt;/code&gt;) and a setter should be named &lt;code&gt;SetFieldName&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="5---interface-pollution"&gt;5 - Interface pollution&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Go&amp;rsquo;s interfaces are satisfied implicitly (structural typing).&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&amp;ldquo;The bigger the interface, the weaker the abstraction.&amp;rdquo;&lt;/em&gt; — Rob Pike&lt;/li&gt;
&lt;li&gt;When to use interfaces
&lt;ul&gt;
&lt;li&gt;Common behavior
&lt;ul&gt;
&lt;li&gt;The behavior is factored out into an interface when it is common to multiple types (e.g., &lt;code&gt;sort.Interface&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Decoupling
&lt;ul&gt;
&lt;li&gt;The implementation is decoupled from the interface, which allows for easier testing and swapping of implementations.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Restricting behavior
&lt;ul&gt;
&lt;li&gt;The interface restricts the behavior of the type, which can be useful for enforcing constraints. For example, the &lt;code&gt;io.Reader&lt;/code&gt; interface restricts the behavior of the type to reading. It is possible to enforce constraints such as with a getter interface that only has a &lt;code&gt;Get&lt;/code&gt; method and prevents setting values.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Interface pollution
&lt;ul&gt;
&lt;li&gt;Abstractions should be discovered, not invented. Only create interfaces when they are needed.&lt;/li&gt;
&lt;li&gt;Adding levels of indirection makes the code harder to understand.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="6---interface-on-the-producer-side"&gt;6 - Interface on the producer side&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Producer side&lt;/em&gt; refers to an interface defined in the same package as the type that satisfies it.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Consumer side&lt;/em&gt; refers to an interface defined in a package that uses it and which is independent of the package that implements the interface.&lt;/li&gt;
&lt;li&gt;The client should determine the level of abstraction it needs.&lt;/li&gt;
&lt;li&gt;This relates to the &lt;em&gt;Interface segregation principle&lt;/em&gt; of SOLID.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="7---returning-interfaces"&gt;7 - Returning interfaces&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;In many cases, this is a bad practice in Go.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&amp;ldquo;Be conservative in what you do, be liberal in what you accept from others.&amp;rdquo;&lt;/em&gt; — Transmission Control Protocol
&lt;ul&gt;
&lt;li&gt;Return structs instead of interfaces.&lt;/li&gt;
&lt;li&gt;Accept interfaces if possible.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Interfaces might be returned (e.g., &lt;code&gt;io.Reader&lt;/code&gt;), but this should be done with caution. It&amp;rsquo;s usually done when the interface itself is implemented on the producer side (e.g., standard library) and the consumer side (e.g., user code) is expected to use it.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="8---any-says-nothing"&gt;8 - &lt;code&gt;any&lt;/code&gt; says nothing&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;interface{}&lt;/code&gt; type is a placeholder for &lt;code&gt;any&lt;/code&gt; type. &lt;code&gt;any&lt;/code&gt; is an alias for &lt;code&gt;interface{}&lt;/code&gt; since Go 1.18.&lt;/li&gt;
&lt;li&gt;It requires a type assertion to be used.&lt;/li&gt;
&lt;li&gt;Using &lt;code&gt;any&lt;/code&gt; does not convey any meaningful information about the type.&lt;/li&gt;
&lt;li&gt;It will lead to issues compilation-wise.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="9---being-confused-about-when-to-use-generics"&gt;9 - Being confused about when to use generics&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;A &amp;ldquo;type parameter&amp;rdquo; is a placeholder for a type that is specified when the function is called.&lt;/li&gt;
&lt;li&gt;A constraint is a condition that the type parameter must satisfy (e.g., implement an interface like &lt;code&gt;comparable&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;intStringConstraint&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;interface&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;~&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;~&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// ^--- union operator&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;The union operator (&lt;code&gt;|&lt;/code&gt;) is used to specify that the type parameter must be either &lt;code&gt;int&lt;/code&gt; or &lt;code&gt;string&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The tilde (&lt;code&gt;~&lt;/code&gt;) is used to restrict all the underlying types of the type parameter to the specified types.&lt;/li&gt;
&lt;li&gt;Common uses and misuses
&lt;ul&gt;
&lt;li&gt;Generics are useful to factor out common behavior (e.g, the &lt;code&gt;sort&lt;/code&gt; interface).
&lt;ul&gt;
&lt;li&gt;Data structures (e.g., binary tree, linked list, heap).&lt;/li&gt;
&lt;li&gt;Functions working with slice, map, channels of any type.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Generics are not useful when the behavior is not common.
&lt;ul&gt;
&lt;li&gt;If the method of the type argument is called, then the generic should be removed in the function received and a type should be specified in the function parameter.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Generics do not shine when they make the code more complex. Unnecessary abstraction should be avoided.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="10---not-being-aware-of-the-possible-problems-with-type-embedding"&gt;10 - Not being aware of the possible problems with type embedding&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;A type embedding is a way to reuse the fields and methods of a type in another type. The fields from that other type get &amp;ldquo;promoted&amp;rdquo; to the new type (i.e., they can be accessed directly from the new type, as well as through the embedded type).&lt;/li&gt;
&lt;li&gt;Incorrect usage
&lt;ul&gt;
&lt;li&gt;An example of a wrong use of type embedding is a &lt;code&gt;sync.Mutex&lt;/code&gt; embedded in a struct. It will be available outside the struct and can be misused.&lt;/li&gt;
&lt;li&gt;It shouldn&amp;rsquo;t be used only as syntactic sugar to access the methods of the embedded type. Use a field instead.&lt;/li&gt;
&lt;li&gt;It shouldn&amp;rsquo;t promote fields that are not intended to be used outside the struct (e.g., &lt;code&gt;sync.Mutex&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Correct usage
&lt;ul&gt;
&lt;li&gt;A custom logger that wants to write and close may embed a &lt;code&gt;io.WriteCloser&lt;/code&gt; interface so that both methods are available. They will be promoted to the new type and there won&amp;rsquo;t be a need to implement these methods simply to forward a call to the embedded type.&lt;/li&gt;
&lt;li&gt;Preventing type embeddings in public structs is probably the safest route.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Embedding vs. OOP subclassing
&lt;ul&gt;
&lt;li&gt;Embedding is not subclassing. It is a way to reuse fields and methods of a type in another type. It is a form of composition.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="11---not-using-the-functional-options-pattern"&gt;11 - Not using the functional options pattern&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Config struct
&lt;ul&gt;
&lt;li&gt;This is limited because to bring flexibility and distinguish between the zero value and the default value, one must use pointers.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Builder pattern
&lt;ul&gt;
&lt;li&gt;To keep chaining method calls, one should not return an error, which means validation is delayed.&lt;/li&gt;
&lt;li&gt;To have proper error handling along the way, it makes the configuration more complex than it needs to be.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Functional options pattern
&lt;ul&gt;
&lt;li&gt;This pattern makes use of closures to set the configuration options, where the closure is an anonymous function being returned.&lt;/li&gt;
&lt;li&gt;The closure is called with the configuration struct as an argument, and it sets the configuration options.&lt;/li&gt;
&lt;li&gt;This pattern allows for validation of the configuration options and for the configuration to be set in a single call.&lt;/li&gt;
&lt;li&gt;It is a flexible pattern that allows for the configuration to be set in any order and for the configuration to be validated at the time of setting.&lt;/li&gt;
&lt;li&gt;One does not need to provide a default value for the configuration struct since the function accepts variadic arguments, which may be empty.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="12---project-misorganization"&gt;12 - Project misorganization&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Project structure
&lt;ul&gt;
&lt;li&gt;The &lt;a href="https://github.com/golang-standards/project-layout"&gt;&lt;code&gt;project-layout&lt;/code&gt;&lt;/a&gt; is a great place to start for a complex application. Despite not being an official standard, it is a great and logically sound starting point.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Package organization
&lt;ul&gt;
&lt;li&gt;There is no concept of subpackages in Go. Sub-directories are useful to have high cohesion.&lt;/li&gt;
&lt;li&gt;Hexagonal architecture group per technical layer.&lt;/li&gt;
&lt;li&gt;An alternative is to group by context (e.g., customer context, contract context).&lt;/li&gt;
&lt;li&gt;Avoid both nano and huge packages.
&lt;ul&gt;
&lt;li&gt;Nano packages probably mean there&amp;rsquo;s lack of understanding about the connections between the different files.&lt;/li&gt;
&lt;li&gt;Huge packages dilute the meaning of the package.&lt;/li&gt;
&lt;li&gt;Name a package after what they &lt;em&gt;provide&lt;/em&gt;, not what they &lt;em&gt;contain&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&amp;ldquo;Package names should be short, concise, expressive and, by convention, a single lowercase word&amp;rdquo;&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Minimize what should be exported as much as possible to reduce coupling.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="13---creating-utility-packages"&gt;13 - Creating utility packages&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;utils&lt;/code&gt;, &lt;code&gt;common&lt;/code&gt;, &lt;code&gt;base&lt;/code&gt;&amp;hellip; bad practice.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;util&lt;/code&gt; is meaningless.&lt;/li&gt;
&lt;li&gt;While nano packages should be avoided, if a few functions are highly cohesive and don&amp;rsquo;t belong anywhere else, it&amp;rsquo;s a good idea to keep them separate with good naming.&lt;/li&gt;
&lt;li&gt;Make APIs expressive.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="14---ignoring-package-name-collisions"&gt;14 - Ignoring package name collisions&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Naming a variable the same as a package name will shadow the package name.&lt;/li&gt;
&lt;li&gt;Either rename the variable (&lt;code&gt;redisClient := redis.NewClient()&lt;/code&gt;) or rename the import with an alias (&lt;code&gt;import redisapi &amp;quot;mylib/redis&amp;quot;&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;The same is true for built-in functions like &lt;code&gt;copy&lt;/code&gt;: they shouldn&amp;rsquo;t be shadowed.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="15---missing-code-documentation"&gt;15 - Missing code documentation&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Simplifies how clients consume an API.&lt;/li&gt;
&lt;li&gt;Helps in maintaining a project.&lt;/li&gt;
&lt;li&gt;In Go, every exported element should be documented, starting with the name of the element being documented (e.g., &lt;code&gt;Customer is ...&lt;/code&gt;). It should be a complete sentence ending with a period.&lt;/li&gt;
&lt;li&gt;An element can be marked as deprecated with a comment starting with &lt;code&gt;Deprecated:&lt;/code&gt; after the description of the element.&lt;/li&gt;
&lt;li&gt;The convention to document a package is to have a comment at the top of the file with the package name and a description of the package, starting with &lt;code&gt;// Package packageName ...&lt;/code&gt;. The first line should be concise, then a blank line, then a more detailed description.&lt;/li&gt;
&lt;li&gt;Comments at the top of the file will be omitted from the documentation if they are followed by a blank line and more comments.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="16---not-using-linters"&gt;16 - Not using linters&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Automatic tool to analyze code and catch errors.&lt;/li&gt;
&lt;li&gt;They help prevent mistakes automatically and consistently.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="data-types"&gt;Data types&lt;/h2&gt;
&lt;h3 id="17---creating-confusion-with-octal-literals"&gt;17 - Creating confusion with octal literals&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Using &lt;code&gt;0o&lt;/code&gt; instead of &lt;code&gt;0&lt;/code&gt; for octal literals is clearer.&lt;/li&gt;
&lt;li&gt;Octal is still useful to express file permissions (e.g., &lt;code&gt;0644&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Go supports using underscores in numeric literals to improve readability (e.g., &lt;code&gt;1_000_000&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="18---neglecting-integer-overflows"&gt;18 - Neglecting integer overflows&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;It won&amp;rsquo;t panic at runtime. They are silent bugs.&lt;/li&gt;
&lt;li&gt;It will wrap around.&lt;/li&gt;
&lt;li&gt;Use the &lt;code&gt;math&lt;/code&gt; package to check for overflows.&lt;/li&gt;
&lt;li&gt;Detecting integer overflow when incrementing
&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;math.MaxInt&lt;/code&gt;, &lt;code&gt;math.MinInt&lt;/code&gt;, &lt;code&gt;math.MaxUint&lt;/code&gt;, &lt;code&gt;math.MinUint&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Detecting integer overflows during addition
&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;math.MaxInt - a &amp;lt; b&lt;/code&gt; or &lt;code&gt;math.MaxUint - a &amp;lt; b&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Detecting integer overflows during multiplication
&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;math.MaxInt/a &amp;lt; b&lt;/code&gt; or &lt;code&gt;math.MaxUint/a &amp;lt; b&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="19---not-understanding-floating-points"&gt;19 - Not understanding floating points&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;em&gt;mantissa&lt;/em&gt; is the significant part of a floating-point number.&lt;/li&gt;
&lt;li&gt;The &lt;em&gt;exponent&lt;/em&gt; is the power of 10 by which the mantissa is multiplied.&lt;/li&gt;
&lt;li&gt;For &lt;code&gt;float32&lt;/code&gt;, the mantissa is 23 bits and the exponent is 8 bits.&lt;/li&gt;
&lt;li&gt;For &lt;code&gt;float64&lt;/code&gt;, the mantissa is 52 bits and the exponent is 11 bits, the remaining bit is the sign bit.&lt;/li&gt;
&lt;li&gt;It is best to avoid comparing by equality with floating-point numbers and instead use a tolerance (delta).&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;math.IsInf&lt;/code&gt; and &lt;code&gt;math.IsNaN&lt;/code&gt; to check for infinity and NaN.&lt;/li&gt;
&lt;li&gt;Group floating-point numbers together by their magnitude to reduce precision loss when adding and subtracting.&lt;/li&gt;
&lt;li&gt;With calculations involving both addition/subtraction and multiplication/division, it is best to perform the multiplication/division first to reduce precision loss.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="20---not-understanding-slice-length-and-capacity"&gt;20 - Not understanding slice length and capacity&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Slice data is stored contiguously in an array data structure.&lt;/li&gt;
&lt;li&gt;A slice holds a pointer to the array, the length of the slice, and the capacity of the slice.&lt;/li&gt;
&lt;li&gt;Trying to access an index greater than the length of the slice will result in a runtime panic, even though the capacity is greater.&lt;/li&gt;
&lt;li&gt;Slicing a slice will create a new slice with the same underlying array, but with a different length and capacity.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;append&lt;/code&gt; function will create a new slice with a new underlying array if the capacity is exceeded.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="21---inefficient-slice-initialization"&gt;21 - Inefficient slice initialization&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;make&lt;/code&gt; to initialize a slice with a specific length and capacity.&lt;/li&gt;
&lt;li&gt;Set a length of &lt;code&gt;0&lt;/code&gt; (2nd argument to &lt;code&gt;make&lt;/code&gt;) and a capacity of &lt;code&gt;n&lt;/code&gt; (3rd argument to &lt;code&gt;make&lt;/code&gt;), which will reuse the same backing array until the capacity is exceeded.&lt;/li&gt;
&lt;li&gt;One can also set only the length and use direct assignment instead of &lt;code&gt;append&lt;/code&gt; (&lt;code&gt;bars[i] = fooToBar(foo)&lt;/code&gt;). This is about 400% faster than using an empty slice.&lt;/li&gt;
&lt;li&gt;If the length of the slice is already known, it is better to take advantage of it and set the length of the slice when initializing it.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="22---being-confused-about-nil-vs-empty-slices"&gt;22 - Being confused about nil vs. empty slices&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;A slice is empty if its length is equal to 0.&lt;/li&gt;
&lt;li&gt;A slice is &lt;code&gt;nil&lt;/code&gt; if it equals &lt;code&gt;nil&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;nil&lt;/code&gt; slice is an empty slice.&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;nil&lt;/code&gt; slice can be passed in a single line: &lt;code&gt;s := append([]int(nil), 42)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;A nil slice is marshaled as a &lt;code&gt;null&lt;/code&gt; element, whereas a non-nil, empty slice is marshaled as an empty array.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="23---not-properly-checking-if-a-slice-is-empty"&gt;23 - Not properly checking if a slice is empty&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&amp;quot;[&amp;hellip;] when designing interfaces, we should avoid distinguishing nil and empty slices, which leads to subtle programming errors&amp;quot;&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&amp;ldquo;This principle is the same with maps. To check if a map is empty, check its length, not whether it&amp;rsquo;s nil&amp;rdquo;&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Do &lt;code&gt;len(slice) != 0&lt;/code&gt; instead of &lt;code&gt;slice != nil&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="24---not-making-slice-copies-correctly"&gt;24 - Not making slice copies correctly&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The destination slice must have the same length as the source slice (or greater). Else, the copy will match the length of the destination slice and may be missing elements.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;copy&lt;/code&gt; is the more idiomatic way to copy slices (vs. &lt;code&gt;dst := append([]int(nil), src...)&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="25---unexpected-side-effects-using-slice-append"&gt;25 - Unexpected side effects using slice &lt;code&gt;append&lt;/code&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;If the resulting slice as a length smaller than the capacity, the slice will be modified in place and will have unintended side effects.&lt;/li&gt;
&lt;li&gt;To avoid side effects outside a given range of a slice, &lt;em&gt;full slice expression&lt;/em&gt; can be used (e.g., &lt;code&gt;s := []int{1, 2, 3}&lt;/code&gt;, then &lt;code&gt;s[:2:2]&lt;/code&gt; will create a new slice with a length of 2 and a capacity of 2).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="26---slices-and-memory-leaks"&gt;26 - Slices and memory leaks&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Leaking capacity
&lt;ul&gt;
&lt;li&gt;Slicing a huge slice to a smaller slice will keep the capacity of the original slice. This makes matters worst if the result of a slice is kept for many iterations in a loop.&lt;/li&gt;
&lt;li&gt;Instead, use &lt;code&gt;copy&lt;/code&gt; to create a new slice with the necessary length.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Leakage with full slice expressions
&lt;ul&gt;
&lt;li&gt;The issue is the same as with slicing.&lt;/li&gt;
&lt;li&gt;The solution is the same as with slicing.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Slice and pointers
&lt;ul&gt;
&lt;li&gt;A slice holds a pointer to an array, so if the slice is kept, the array will be kept in memory.&lt;/li&gt;
&lt;li&gt;To avoid this, use &lt;code&gt;copy&lt;/code&gt; to create a new slice with the necessary length.&lt;/li&gt;
&lt;li&gt;If however we want to keep the original capacity, we can set all the unneeded elements to &lt;code&gt;nil&lt;/code&gt; explicitly. For instance, all elements but the first 2:&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;foos&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;foos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="27---inefficient-map-initialization"&gt;27 - Inefficient map initialization&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Maps are unordered collections of key-value pairs, where all keys are unique. They use hash tables under the hood.&lt;/li&gt;
&lt;li&gt;Insertion can be an &lt;code&gt;O(n)&lt;/code&gt; operation if the map is resized.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;make&lt;/code&gt; can be used to initialize a map with a specific size (second argument to &lt;code&gt;make&lt;/code&gt;, without capacity). This avoids having to grow the map and re-balancing all the buckets of 8 elements each.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="28---maps-and-memory-leaks"&gt;28 - Maps and memory leaks&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The number of buckets in a map cannot shrink. Removing elements from a map will not reduce the number of buckets.&lt;/li&gt;
&lt;li&gt;Even the overflown buckets will not be reduced.&lt;/li&gt;
&lt;li&gt;One possible solution: periodically copy the map to a new map.
&lt;ul&gt;
&lt;li&gt;Downside: the amount of memory used will be doubled for a short period of time.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Another solution: update the value type of the map to store an array pointer.
&lt;ul&gt;
&lt;li&gt;The peak memory consumed will be far less.&lt;/li&gt;
&lt;li&gt;The garbage collection will be more efficient.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="29---comparing-values-incorrectly"&gt;29 - Comparing values incorrectly&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;==&lt;/code&gt; does not work for slices, maps, and functions.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;reflect.DeepEqual&lt;/code&gt; could be used, but it&amp;rsquo;s about 100x slower than &lt;code&gt;==&lt;/code&gt;, and so might be better used for testing only.&lt;/li&gt;
&lt;li&gt;If strict comparison is needed on structs and good performance is required, consider using a custom comparison function.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="control-structures"&gt;Control structures&lt;/h2&gt;
&lt;h3 id="30---ignoring-the-fact-that-elements-are-copied-in-range-loops"&gt;30 - Ignoring the fact that elements are copied in range loops&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;In Go, every assignment leads to a copy of the value.&lt;/li&gt;
&lt;li&gt;In a range loop, the value is copied, not the reference.&lt;/li&gt;
&lt;li&gt;To update a slice with a range loop, one must use the index to update the slice, i.e., &lt;code&gt;for i := range s { s[i] = ... }&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;A classic &lt;code&gt;for&lt;/code&gt; loop can be used to update the slice in place, i.e., &lt;code&gt;for i := 0; i &amp;lt; len(s); i++ { s[i] = ... }&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Using a pointer to a slice will allow for the slice to be updated in place, but iterating over such a slice is less efficient for the CPU.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="31---ignoring-how-arguments-are-evaluated-in-range-loops"&gt;31 - Ignoring how arguments are evaluated in range loops&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Looping over an array will copy the value of the array element.&lt;/li&gt;
&lt;li&gt;Using a pointer to the array will allow for the array to be updated in place and will avoid copying values, which may be more efficient, especially on large arrays.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;range&lt;/code&gt; loop evaluates the expression to its right only once, so if the expression is a slice, the slice will not be updated in the loop.&lt;/li&gt;
&lt;li&gt;To access updated elements of a slice during iteration with a &lt;code&gt;range&lt;/code&gt; loop, one must use the index to access the element in the slice, not the value of the element, since the expression is copied to a temporary variable.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="32---ignoring-the-impact-of-using-pointer-elements-in-range-loops"&gt;32 - Ignoring the impact of using pointer elements in range loops&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Using a pointer to a slice when looping with a &lt;code&gt;range&lt;/code&gt; loop can lead to storing the address of the temporary variable in the slice for all elements in the slice.&lt;/li&gt;
&lt;li&gt;To avoid this issue, one can create a local variable for each element to be iterated over in the slice and then use the local variable in the loop to perform assignments.&lt;/li&gt;
&lt;li&gt;Another solution is to use a &lt;code&gt;range&lt;/code&gt; loop with the index, create a temporary variable by dereferencing the pointer, and then assign the temporary variable to the slice.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="33---making-wrong-assumptions-during-map-iterations"&gt;33 - Making wrong assumptions during map iterations&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Maps don&amp;rsquo;t sort keys.&lt;/li&gt;
&lt;li&gt;Insertion order is not preserved.&lt;/li&gt;
&lt;li&gt;Iteration order is unspecified. This is a conscious language design choice so that developers don&amp;rsquo;t rely on the order of the keys.&lt;/li&gt;
&lt;li&gt;One should work on a copy of a map if new elements are to be added or removed during iteration.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="34---ignoring-how-the-break-statement-works"&gt;34 - Ignoring how the break statement works&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;break&lt;/code&gt; works on the innermost loop, whether that be a &lt;code&gt;for&lt;/code&gt;, &lt;code&gt;switch&lt;/code&gt;, or &lt;code&gt;select&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;To break outside of a loop, one can use a label.&lt;/li&gt;
&lt;li&gt;A label can be an idiomatic way to break out of nested loops, as is done in the &lt;code&gt;net/http&lt;/code&gt; package with a &lt;code&gt;readlines:&lt;/code&gt; label.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="35---using-defer-inside-a-loop"&gt;35 - Using &lt;code&gt;defer&lt;/code&gt; inside a loop&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;defer&lt;/code&gt; is a statement that schedules a function to be called when the surrounding function returns. That is, it won&amp;rsquo;t run on each iteration of the loop until it returns, if ever.&lt;/li&gt;
&lt;li&gt;To avoid resource leaks like this, each iteration of the loop can use a separate function that is run and defers the cleanup.&lt;/li&gt;
&lt;li&gt;Another solution is to use a closure, but this can be less readable.&lt;/li&gt;
&lt;li&gt;A function call will decrease performance slightly, so if performance is a concern, the &lt;code&gt;defer&lt;/code&gt; call should be handled manually before the loop.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="strings"&gt;Strings&lt;/h2&gt;
&lt;h3 id="36---not-understanding-the-concept-of-a-rune"&gt;36 - Not understanding the concept of a rune&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;A charset is a set of characters.&lt;/li&gt;
&lt;li&gt;An encoding describes how to translate a character set into a sequence of bytes.&lt;/li&gt;
&lt;li&gt;In Go, a string is a reference to an immutable slice of bytes.&lt;/li&gt;
&lt;li&gt;A rune is a Unicode code point.&lt;/li&gt;
&lt;li&gt;Source code in Go is encoded in UTF-8: string literals will then also be encoded in UTF-8.&lt;/li&gt;
&lt;li&gt;UTF-8 is a variable-length encoding, where each code point is represented by one to four bytes. For instance, the string &lt;code&gt;hello&lt;/code&gt; is represented by five bytes, but the string containing the character &lt;code&gt;汉&lt;/code&gt; is represented by three bytes, which we can check with &lt;code&gt;len(&amp;quot;汉&amp;quot;)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;A rune is an alias for &lt;code&gt;int32&lt;/code&gt; (4 bytes = 32 bits).&lt;/li&gt;
&lt;li&gt;The repository &lt;code&gt;golang.org/x&lt;/code&gt; contains extensions to work with UTF-16 and UTF-32.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="37---inaccurate-string-iteration"&gt;37 - Inaccurate string iteration&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;With the &lt;code&gt;unicode/utf8&lt;/code&gt; package, one can use &lt;code&gt;utf8.RuneCountInString(s)&lt;/code&gt; to count the number of runes in a string.&lt;/li&gt;
&lt;li&gt;Accessing specific runes can be done without converting the string if characters are in the ASCII range.&lt;/li&gt;
&lt;li&gt;It is most useful to convert a string to a slice of runes when a specific rune is required by index.&lt;/li&gt;
&lt;li&gt;Iterating over the runes with a &lt;code&gt;for range&lt;/code&gt; loop returns the starting index of the rune and the rune itself.&lt;/li&gt;
&lt;li&gt;Iterating with a &lt;code&gt;for range&lt;/code&gt; using only the index returns the starting index of the rune and the byte value at that position.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="38---misusing-trim-functions"&gt;38 - Misusing trim functions&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;TrimRight&lt;/code&gt; to remove trailing characters. Go backwards until a rune is not in the set of characters to be trimmed.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;TrimSuffix&lt;/code&gt; to remove a suffix (only one substring occurrence).&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;TrimLeft&lt;/code&gt; to remove leading characters. Go forwards until a rune is not in the set of characters to be trimmed.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;TrimPrefix&lt;/code&gt; to remove a prefix (only one substring occurrence).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="39---under-optimized-string-concatenation"&gt;39 - Under-optimized string concatenation&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;+=&lt;/code&gt; is inefficient for string concatenation because it creates a new string each time.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;strings.Builder&lt;/code&gt; for efficient string concatenation.&lt;/li&gt;
&lt;li&gt;Call &lt;code&gt;Grow&lt;/code&gt; on the builder to allocate memory for the string.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="40---useless-string-conversions"&gt;40 - Useless string conversions&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Working with &lt;code&gt;[]byte&lt;/code&gt; is more efficient than working with strings due to many interfaces in the standard library taking &lt;code&gt;[]byte&lt;/code&gt; as input, which avoids doing a conversion.&lt;/li&gt;
&lt;li&gt;Most methods in the &lt;code&gt;strings&lt;/code&gt; package have a &lt;code&gt;[]byte&lt;/code&gt; counterpart in the &lt;code&gt;bytes&lt;/code&gt; package.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="41---substrings-and-memory-leaks"&gt;41 - Substrings and memory leaks&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;A substring shares the same backing array as the original string.&lt;/li&gt;
&lt;li&gt;If the substring is kept, the original string will be kept in memory.&lt;/li&gt;
&lt;li&gt;To avoid this, either use &lt;code&gt;string([]byte(theString[:n]))&lt;/code&gt; to slice the needed part of the string or &lt;code&gt;strings.Clone&lt;/code&gt; to create a new string.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="functions-and-methods"&gt;Functions and methods&lt;/h2&gt;
&lt;h3 id="42---not-knowing-which-type-of-receiver-to-use"&gt;42 - Not knowing which type of receiver to use&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Go does not pass values by reference.&lt;/li&gt;
&lt;li&gt;A value receiver makes a copy of the value: changes are local to the method.&lt;/li&gt;
&lt;li&gt;A pointer receiver passes the memory address of the value: changes are global to the value. Strictly speaking, this is still a copy, but the copy is made for a pointer.&lt;/li&gt;
&lt;li&gt;Use a pointer receiver when:
&lt;ul&gt;
&lt;li&gt;The method needs to mutate the receiver.&lt;/li&gt;
&lt;li&gt;The method receiver contains a field that cannot be copied.&lt;/li&gt;
&lt;li&gt;The receiver is a large struct.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use a value receiver when:
&lt;ul&gt;
&lt;li&gt;Enforcing immutability.&lt;/li&gt;
&lt;li&gt;The receiver is a &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;func&lt;/code&gt; or &lt;code&gt;chan&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;A slice that doesn&amp;rsquo;t have to be mutated.&lt;/li&gt;
&lt;li&gt;The receiver is a small struct or array with no mutable fields, like &lt;code&gt;time.Time&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The receiver is a basic type, like &lt;code&gt;int&lt;/code&gt;, &lt;code&gt;float64&lt;/code&gt;, or &lt;code&gt;string&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Mixing value and pointer receivers can lead to confusion and bugs: this should generally be avoided (although the standard library shows some exceptions, like &lt;code&gt;time.Time&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Defaulting to a value receiver is a good practice, unless there is a good reason to use a pointer receiver.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="43---never-using-named-result-parameters"&gt;43 - Never using named result parameters&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Only use named result parameters when they make the code more readable (e.g., returning two &lt;code&gt;int&lt;/code&gt; can be ambiguous).&lt;/li&gt;
&lt;li&gt;Use naked returns only when the function is short and the return values are clear.&lt;/li&gt;
&lt;li&gt;For an interface definition, named result parameters are useful to document the return values.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="44---unintended-side-effects-with-named-result-parameters"&gt;44 - Unintended side effects with named result parameters&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Named result parameters are &lt;em&gt;initialized to their zero value&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Using named result parameters doesn&amp;rsquo;t mean one has to use naked returns: clarity is more important than brevity.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="45---returning-a-nil-receiver"&gt;45 - Returning a nil receiver&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;A nil receiver is a pointer to a struct that has not been initialized.&lt;/li&gt;
&lt;li&gt;Instead of returning a pointer to a struct (which will return a non-nil pointer to a nil struct), return &lt;code&gt;nil&lt;/code&gt; directly.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="46---using-a-filename-as-a-function-input"&gt;46 - Using a filename as a function input&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;It is more idiomatic and flexible to use an &lt;code&gt;io.Reader&lt;/code&gt; or &lt;code&gt;io.Writer&lt;/code&gt; as an input to a function that reads or writes to a file: this abstracts the data source.&lt;/li&gt;
&lt;li&gt;This allows for the function to be used with any type that implements the &lt;code&gt;io.Reader&lt;/code&gt; or &lt;code&gt;io.Writer&lt;/code&gt; interface, not just a file.&lt;/li&gt;
&lt;li&gt;It makes testing easier, as one can pass in a &lt;code&gt;bytes&lt;/code&gt; buffer instead of a file, for instance.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="47---ignoring-how-defer-arguments-and-receivers-are-evaluated"&gt;47 - Ignoring how defer arguments and receivers are evaluated&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The arguments to a &lt;code&gt;defer&lt;/code&gt; statement are evaluated when the &lt;code&gt;defer&lt;/code&gt; statement is executed, not when the deferred function is executed.
&lt;ul&gt;
&lt;li&gt;That means that if a variable is initialized with a zero value and passed to &lt;code&gt;defer&lt;/code&gt; as is, the deferred function will receive the zero value.&lt;/li&gt;
&lt;li&gt;To avoid this pitfall, one can use a pointer to the variable, which will be evaluated when the deferred function is executed. The memory address will not change, but the value at that address will.&lt;/li&gt;
&lt;li&gt;Another solution is to use a closure to capture the value of the variable at the time the &lt;code&gt;defer&lt;/code&gt; statement is executed.
&lt;ul&gt;
&lt;li&gt;This works because the values of the variables are evaluated when the closure runs, not when the closure is created.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;In the case of a method receiver, data in the receiver is evaluated when the &lt;code&gt;defer&lt;/code&gt; statement is executed, leading to the same situation as with arguments.
&lt;ul&gt;
&lt;li&gt;A pointer receiver can be used to avoid this issue, as the updated value of the pointer will be visible to the deferred function when it is executed.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="error-management"&gt;Error management&lt;/h2&gt;
&lt;h3 id="48---panicking"&gt;48 - Panicking&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;It is used to signal genuinely unexpected errors, such as programming errors (e.g., &lt;code&gt;net/http&lt;/code&gt; checking for a status code outside the valid range).&lt;/li&gt;
&lt;li&gt;Another use case for &lt;code&gt;panic&lt;/code&gt; is when the application requires a dependency but fails to initialize it (e.g., a regular expression).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="49---ignoring-when-to-wrap-an-error"&gt;49 - Ignoring when to wrap an error&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;%w&lt;/code&gt; is used to wrap an error conveniently.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;%v&lt;/code&gt; directive will print the transformed error message, but &lt;code&gt;%w&lt;/code&gt; will print the error message and the wrapped error message.&lt;/li&gt;
&lt;li&gt;If a caller relies on unwrapping an error provided with &lt;code&gt;%w&lt;/code&gt;, it leads to coupling: if the underlying implementation that is wrapped changes, the caller will break.&lt;/li&gt;
&lt;li&gt;To mark an error, one should use a custom error type.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="50---checking-an-error-type-inaccurately"&gt;50 - Checking an error type inaccurately&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;errors.As&lt;/code&gt; is used to check if an error is of a specific type anywhere in the error chain.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;errors.As&lt;/code&gt; should be used whenever error wrapping is used.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="51---checking-an-error-value-inaccurately"&gt;51 - Checking an error value inaccurately&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;A sentinel error is a predefined error that can be compared to an error value. It is about an &amp;ldquo;expected&amp;rdquo; error (e.g., &lt;code&gt;sql.ErrNoRows&lt;/code&gt; and &lt;code&gt;io.EOF&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Unexpected errors should be implemented as error types, implementing the &lt;code&gt;error&lt;/code&gt; interface.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;errors.Is&lt;/code&gt; is used to check if an error is equal to a sentinel error (not &lt;code&gt;==&lt;/code&gt;! if the error is wrapped, it will not be equal to the sentinel error).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="52---handling-an-error-twice"&gt;52 - Handling an error twice&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Logging the same error twice can lead to confusion.&lt;/li&gt;
&lt;li&gt;Logging an error is handling an error! One should not both log and return an error.&lt;/li&gt;
&lt;li&gt;Error wrapping is useful to provide context to an error when propagating it up the call stack.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="53---not-handling-an-error"&gt;53 - Not handling an error&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The only way to explicitly ignore an error is to assign it to the blank identifier &lt;code&gt;_&lt;/code&gt;. Adding a comment about why the error is ignored is a good practice.&lt;/li&gt;
&lt;li&gt;Do not simply ignore the assignment.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="54---not-handling-defer-errors"&gt;54 - Not handling defer errors&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Errors should be handled or explicitly ignored in &lt;code&gt;defer&lt;/code&gt; functions.&lt;/li&gt;
&lt;li&gt;To return an error to the caller via the &lt;code&gt;defer&lt;/code&gt; function, one can use a named return parameter, assigning the error to it.&lt;/li&gt;
&lt;li&gt;Instead of returning multiple errors from a &lt;code&gt;defer&lt;/code&gt; function, it may be a good idea to log one error and return the other, depending on the context.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="concurrency-foundations"&gt;Concurrency: Foundations&lt;/h2&gt;
&lt;h3 id="55---mixing-up-concurrency-and-parallelism"&gt;55 - Mixing up concurrency and parallelism&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Concurrency is about structuring a program, while parallelism is about running multiple tasks at the same time.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Concurrency enables parallelism&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="56---thinking-concurrency-is-always-faster"&gt;56 - Thinking concurrency is always faster&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;A thread is the smallest unit of execution that can be scheduled by an operating system.&lt;/li&gt;
&lt;li&gt;A goroutine is a lightweight thread managed by the Go runtime: it is context-switched on and off by an OS thread.&lt;/li&gt;
&lt;li&gt;A goroutine has a memory footprint of 2 KB, while a thread has a memory footprint of ~2 MB.&lt;/li&gt;
&lt;li&gt;There is a point of diminishing returns when creating too many goroutines: one must take into account the overhead of context switching and determine the size of the workload that will be processed by each goroutine.&lt;/li&gt;
&lt;li&gt;It is often best to start with a sequential solution and use profiling tools to determine where to add concurrency.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="57---being-puzzled-about-when-to-use-channels-or-mutexes"&gt;57 - Being puzzled about when to use channels or mutexes&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Synchronization between parallel goroutines is achieved with mutexes (mutex stands for &lt;em&gt;mutual exclusion&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;Channels are used to communicate between goroutines. If there are 3 goroutines and a third one needs results from the first two, a channel is the way to go.&lt;/li&gt;
&lt;li&gt;Mutexes ensure exclusive access to a resource (e.g., a map).&lt;/li&gt;
&lt;li&gt;Coordination or ownership of a resource is achieved with channels.&lt;/li&gt;
&lt;li&gt;In general, mutexes are needed for parallel goroutines, whereas channels are needed for concurrent ones.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="58---not-understanding-race-problems"&gt;58 - Not understanding race problems&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;em&gt;data race&lt;/em&gt; occurs when two goroutines access the same variable concurrently and at least one of the accesses is a write.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sync/atomic&lt;/code&gt; provides atomic operations to avoid data races. It works only on primitive types.&lt;/li&gt;
&lt;li&gt;Channels can be used to perform atomic operations on non-primitive types, then send the result over the channel.&lt;/li&gt;
&lt;li&gt;Mutexes can be used to protect a critical section of code.&lt;/li&gt;
&lt;li&gt;The absence of a data race doesn&amp;rsquo;t mean the code will be deterministic: it is possible for goroutines to be scheduled in different orders, leading to a &lt;em&gt;race condition&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;A buffered channel can lead to a data race because a receive from an unbuffered channel happens before the send, but a send to a buffered channel happens before the receive.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="59---not-understanding-the-concurrency-impacts-of-a-workload-type"&gt;59 - Not understanding the concurrency impacts of a workload type&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;A worker pool can be based on &lt;code&gt;GOMAXPROCS&lt;/code&gt; (the number of OS threads) to efficiently distribute the workload when a workload is CPU-bound.&lt;/li&gt;
&lt;li&gt;When a workload is I/O-bound, the number of goroutines can be increased to handle more I/O operations concurrently, depending on the external systems.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="60---misunderstanding-go-contexts"&gt;60 - Misunderstanding Go contexts&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;A context is a way to pass deadlines, cancellation signals, and other request-scoped values across API boundaries and between processes.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;context.Background&lt;/code&gt; is the root context, which is never canceled, has no values, and has no deadline, used when there is no parent context.&lt;/li&gt;
&lt;li&gt;Deadline
&lt;ul&gt;
&lt;li&gt;A deadline is a point in time when the context should be canceled, specified as either a &lt;code&gt;time.Time&lt;/code&gt; or a &lt;code&gt;time.Duration&lt;/code&gt; (time from now).&lt;/li&gt;
&lt;li&gt;Deferring the cancellation of a context can prevent a goroutine from being blocked indefinitely or leaking resources.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Cancellation signals
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;context.WithCancel&lt;/code&gt; returns a copy of the parent context with a new &lt;code&gt;Done&lt;/code&gt; channel.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Context values
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;context.WithValue&lt;/code&gt; returns a copy of the parent context with a key-value pair.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;A function that users wait for should take a context as an argument.&lt;/li&gt;
&lt;li&gt;Prefer &lt;code&gt;context.TODO()&lt;/code&gt; to &lt;code&gt;context.Background()&lt;/code&gt; when a context is needed but there is no parent context, as it better represents the intent.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="concurrency-practice"&gt;Concurrency: Practice&lt;/h2&gt;
&lt;h3 id="61---propagating-an-inappropriate-context"&gt;61 - Propagating an inappropriate context&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Propagating a context is about passing a context from one goroutine to another.&lt;/li&gt;
&lt;li&gt;A context should be passed to a goroutine carefully: if the context requires some values to be passed but the parent goroutine gets its context cancelled, the child goroutine will also be cancelled. This may be undesirable.
&lt;ul&gt;
&lt;li&gt;To avoid this, create a custom struct implementing a context that never expires and that does not carry a cancellation signal, so the values can be passed without the risk of being cancelled.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="62---starting-a-goroutine-without-knowing-when-to-stop-it"&gt;62 - Starting a goroutine without knowing when to stop it&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;A goroutine might loop over the values received from a channel, but if the channel is never closed, this will be a resource leak.&lt;/li&gt;
&lt;li&gt;Passing a context to a goroutine (e.g., to expect a file to be closed) is bad design. Instead, the parent goroutine should be responsible for closing the file by calling a &lt;code&gt;defer&lt;/code&gt; function right after the resource used by another routine is created.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="63---not-being-careful-with-goroutines-and-loop-variables"&gt;63 - Not being careful with goroutines and loop variables&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Spinning up a goroutine inside a &lt;code&gt;for&lt;/code&gt; loop and relying on the loop variable can lead to unexpected behavior.&lt;/li&gt;
&lt;li&gt;Either assign the value of the loop variable to a new variable inside the loop or pass the loop variable as an argument to the goroutine. In the first case, the goroutine could be set up as a closure. In the second case, it would be a regular function call on an anonymous function.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="64---expecting-deterministic-behavior-using-select-and-channels"&gt;64 - Expecting deterministic behavior using select and channels&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;select&lt;/code&gt; statement is used to wait on multiple channels. If multiple channels are ready, one will be chosen semi-randomly.&lt;/li&gt;
&lt;li&gt;Using an unbuffered channel with a &lt;code&gt;select&lt;/code&gt; statement will block until a value is sent on the channel.&lt;/li&gt;
&lt;li&gt;Using a single channel and then checking the message type is an option.&lt;/li&gt;
&lt;li&gt;Using a &lt;code&gt;default&lt;/code&gt; case in a &lt;code&gt;select&lt;/code&gt; statement will allow the program to continue if a channel no longer receives values.
&lt;ul&gt;
&lt;li&gt;This approach works well for multiple channels: when a &lt;code&gt;select&lt;/code&gt; case is chosen, add an inner &lt;code&gt;select&lt;/code&gt; statement to handle the channel. For instance, after a &lt;em&gt;disconnection&lt;/em&gt; message, handle all remaining messages sent the another channel by looping over the channel inside that &lt;code&gt;select&lt;/code&gt; case.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="65---not-using-notification-channels"&gt;65 - Not using notification channels&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;A notification channel is a channel that is used to signal the completion of a task.&lt;/li&gt;
&lt;li&gt;If no data is needed to be sent, a &lt;code&gt;struct{}&lt;/code&gt; can be sent over the channel. This is clearer than sending a &lt;code&gt;bool&lt;/code&gt; or &lt;code&gt;int&lt;/code&gt;. An empty struct occupies no memory.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="66---not-using-nil-channels"&gt;66 - Not using nil channels&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Sending a message to a &lt;code&gt;nil&lt;/code&gt; channel will block forever.&lt;/li&gt;
&lt;li&gt;Receiving from a closed channel is a non-blocking operation: the zero value of the channel type will be returned.&lt;/li&gt;
&lt;li&gt;When looping over multiple channels and using &lt;code&gt;select&lt;/code&gt;, if one of the channels is closed, this will lead to a busy-wait loop.
&lt;ul&gt;
&lt;li&gt;E.g., say we have two channels in a function that are to be &amp;ldquo;merged&amp;rdquo; such that data returned from that function comes from the two channels. If one of the channels is closed, the function will still keep looping over the now invalid &lt;code&gt;select&lt;/code&gt; case.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;To avoid this, one can use a &lt;code&gt;nil&lt;/code&gt; channel to signal a channel is closed. The &lt;code&gt;select&lt;/code&gt; case will be skipped if the channel is &lt;code&gt;nil&lt;/code&gt;, avoiding the busy-wait loop.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="67---being-puzzled-about-channel-size"&gt;67 - Being puzzled about channel size&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;An unbuffered channel (synchronous channel) has a size of 0: the sender blocks until the receiver receives data from the channel.&lt;/li&gt;
&lt;li&gt;With a buffered channel, the sender will block only when the buffer is full.&lt;/li&gt;
&lt;li&gt;An unbuffered channel enables synchronization between goroutines.&lt;/li&gt;
&lt;li&gt;An unbuffered channel can be used as a notification channel via a channel closure (&lt;code&gt;close&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;When using worker pools, a buffered channel can be used to limit the number of tasks that can be processed concurrently, matching the number of goroutines in the pool.&lt;/li&gt;
&lt;li&gt;Rate-limiting can be achieved with a buffered channel, where the buffer size is the number of tasks that can be processed concurrently.&lt;/li&gt;
&lt;li&gt;In a buffered channel, the lower the value, the bigger the impact on CPU. The higher the value, the bigger the impact on memory.&lt;/li&gt;
&lt;li&gt;Buffered channels can lead to obscure deadlocks.&lt;/li&gt;
&lt;li&gt;It&amp;rsquo;s usually best to start with a channel of size &lt;code&gt;1&lt;/code&gt; and perform benchmarks to determine the optimal size.&lt;/li&gt;
&lt;li&gt;Queues tend to be close to full or close to empty anyways (&lt;a href="https://lmax-exchange.github.io/disruptor/files/Disruptor-1.0.pdf"&gt;source&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="68---forgetting-about-possible-side-effects-with-string-formatting"&gt;68 - Forgetting about possible side effects with string formatting&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Printing the values in a context will evaluate the values at the time of the call, which could lead to a data race.&lt;/li&gt;
&lt;li&gt;Acquiring a lock only when it&amp;rsquo;s required is best. This reduces side effects and possible deadlocks. This ties nicely with the fact that a function can go over the &amp;ldquo;error cases&amp;rdquo; before doing anything else that might require more resources (e.g., check the age of a customer is valid before acquiring a lock).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="69---creating-data-races-with-append"&gt;69 - Creating data races with append&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;To prevent data races with &lt;code&gt;append&lt;/code&gt;, one can make a copy of the slice in each goroutine before appending to it.&lt;/li&gt;
&lt;li&gt;If the slice is initialized in such a way that the backing array is shared between goroutines, there will not be a data race since the original slice will remain unchanged.&lt;/li&gt;
&lt;li&gt;Updating a &lt;code&gt;map&lt;/code&gt; from one goroutine will lead to a data race if another goroutine tries to read from the &lt;code&gt;map&lt;/code&gt; at the same time, given that the hashing algorithm for maps introduces some randomness.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="70---using-mutexes-inaccurately-with-slices-and-maps"&gt;70 - Using mutexes inaccurately with slices and maps&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;A mutex is used to protect a critical section of code from being accessed by multiple goroutines at the same time.&lt;/li&gt;
&lt;li&gt;A mutex is used to protect a shared resource, like a slice or a map.&lt;/li&gt;
&lt;li&gt;If an operation is lightweight, it is better to use a mutex to protect the resource (protecting the whole function in the process).&lt;/li&gt;
&lt;li&gt;If an operation is heavy, it is better to make a copy of the resource and then update the copy, then replace the original resource with the copy.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="71---misusing-syncwaitgroup"&gt;71 - Misusing &lt;code&gt;sync.WaitGroup&lt;/code&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Add&lt;/code&gt; must be called in the parent goroutine before the child goroutine is started.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Done&lt;/code&gt; must be called in the child goroutine when the child goroutine is finished.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Wait&lt;/code&gt; must be called in the parent goroutine after all child goroutines have been started.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="72---forgetting-about-synccond"&gt;72 - Forgetting about &lt;code&gt;sync.Cond&lt;/code&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;sync.Cond&lt;/code&gt; is used to signal a condition to multiple goroutines.&lt;/li&gt;
&lt;li&gt;The updater goroutine locks a mutex, updates the condition, unlocks the mutex, and then signals the condition.&lt;/li&gt;
&lt;li&gt;The listener goroutine(s) lock the mutex, wait for the condition to be signaled, and then unlock the mutex.
&lt;ul&gt;
&lt;li&gt;Lock/unlock is done to offset the fact that &lt;code&gt;Wait&lt;/code&gt; unlocks the mutex and then relocks it when the condition is signaled.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;If no goroutines are waiting for the condition when the call to &lt;code&gt;Broadcast&lt;/code&gt; occurs, the signal is lost.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="73---not-using-errgroup"&gt;73 - Not using &lt;code&gt;errgroup&lt;/code&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pkg.go.dev/golang.org/x/sync/errgroup"&gt;errgroup&lt;/a&gt; provides tools to manage a group of goroutines and propagate errors.&lt;/li&gt;
&lt;li&gt;It can be used to share context between goroutines to allow for cancellation of the group of goroutines upon the first error. If 3 calls are made in parallel and one of them fails fast with an error, the other two will be cancelled instead of waiting.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="74---copying-a-sync-type"&gt;74 - Copying a sync type&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;sync.*&lt;/code&gt; types should never be copied.&lt;/li&gt;
&lt;li&gt;If we have a value receiver receiving a struct containing a Mutex, for instance, it will be copied when passed to a function. This will lead to a data race.&lt;/li&gt;
&lt;li&gt;To avoid the issue with a value receiver, either use a pointer receiver or make the mutex field a pointer.&lt;/li&gt;
&lt;li&gt;The same issue will present itself if a function takes a &lt;code&gt;sync.*&lt;/code&gt; type as an argument or if a field in a struct received as a function argument is a &lt;code&gt;sync.*&lt;/code&gt; type.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;go vet&lt;/code&gt; can catch these types of issues.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="the-standard-library"&gt;The standard library&lt;/h2&gt;
&lt;h3 id="75---providing-a-wrong-time-duration"&gt;75 - Providing a wrong time duration&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Always use the &lt;code&gt;time.Duration&lt;/code&gt; API to provide a time duration. Passing any &lt;code&gt;int64&lt;/code&gt; value would work, but the function accepts nanoseconds, which will be confusing.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="76---timeafter-and-memory-leaks"&gt;76 - &lt;code&gt;time.After&lt;/code&gt; and memory leaks&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Resources created by &lt;code&gt;time.After&lt;/code&gt; (e.g., a channel) are released only when the timer expires.&lt;/li&gt;
&lt;li&gt;Using &lt;code&gt;time.After&lt;/code&gt; inside a loop will create a new channel each time the loop iterates, leading to a memory leak. Each call to &lt;code&gt;time.After&lt;/code&gt; will consume about 200 bytes. If this is a long-running loop with frequent events, this can be a significant memory leak (e.g., 5 million calls in an hour would be about 1 GB of wasted memory).&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;time.NewTimer&lt;/code&gt; instead, which will create a timer that can be reset, then listen for the timer to expire on the channel (&lt;code&gt;&amp;lt;-timer.C&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="77---common-json-handling-mistakes"&gt;77 - Common JSON-handling mistakes&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;When unmarshaling JSON, the &lt;code&gt;json&lt;/code&gt; package will not set the fields of a struct to their zero values if the fields are not present in the JSON.&lt;/li&gt;
&lt;li&gt;Type embedding in a struct can be problematic if the embedded type implements the &lt;code&gt;json.Marshaler&lt;/code&gt; interface, which by virtue of being promoted will be used instead of the &lt;code&gt;json.MarshalJSON&lt;/code&gt; method of the struct.
&lt;ul&gt;
&lt;li&gt;Type embedding makes the parent struct implements interfaces of the embedded type.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;If possible, use a named field instead of an anonymous field (type embedding) to avoid this issue.&lt;/li&gt;
&lt;li&gt;Monotonic clocks guarantee that the time will always increase, even if the system clock is changed. This is useful for measuring time intervals.
&lt;ul&gt;
&lt;li&gt;In Go, monotonic time is part of the same API that provides wall time.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;time.Equal&lt;/code&gt; does not take into account the monotonic clock, so it is possible for two times to be equal even if they are not.&lt;/li&gt;
&lt;li&gt;One can also strip away the monotonic time with &lt;code&gt;time.Truncate(0)&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;To prevent time zone issues, use time.LoadLocation&lt;code&gt;to load the desired time zone or use&lt;/code&gt;time.UTC` to work with UTC time.&lt;/li&gt;
&lt;li&gt;Using a map of any to unmarshal JSON may be convenient but has its drawbacks. For instance, numeric values will be unmarshaled as &lt;code&gt;float64&lt;/code&gt;, even if they contain no decimals.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="78---common-sql-mistakes"&gt;78 - Common SQL mistakes&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&amp;ldquo;Forgetting that sql.Open doesn&amp;rsquo;t necessarily establish connections to a database&amp;rdquo;&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;The behavior depends on the SQL driver.&lt;/li&gt;
&lt;li&gt;To make sure the connection is open, one should call &lt;code&gt;Ping&lt;/code&gt; on the connection or use &lt;code&gt;PingContext&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&amp;ldquo;Forgetting about connections pooling&amp;rdquo;&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;SetMaxOpenConns&lt;/code&gt; should be set in any production-grade application to match the load the database can handle.&lt;/li&gt;
&lt;li&gt;If an application generates significant concurrent requests, the default value for &lt;code&gt;SetMaxIdleConns&lt;/code&gt; (2) should be updated.&lt;/li&gt;
&lt;li&gt;If an application can face bursts of requests, one should set &lt;code&gt;SetConnMaxIdleTime&lt;/code&gt; accordingly.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SetConnMaxLifetime&lt;/code&gt; can be useful if an application is behind a load balancer, for example.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&amp;ldquo;Not using prepared statements&amp;rdquo;&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;Prepared statements should be used in untrusted contexts.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&amp;ldquo;Mishandling null values&amp;rdquo;&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;If the value of a column can be &lt;code&gt;NULL&lt;/code&gt;, it should be structured as a pointer to receive &lt;code&gt;nil&lt;/code&gt; values.&lt;/li&gt;
&lt;li&gt;Another approach is to use &lt;code&gt;sql.NullString&lt;/code&gt;, &lt;code&gt;sql.NullInt64&lt;/code&gt;, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&amp;ldquo;Not handling row iteration errors&amp;rdquo;&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;One should check &lt;code&gt;rows.Err&lt;/code&gt; after iterating over rows to check for errors. This is because &lt;code&gt;rows.Next&lt;/code&gt; can stop iterating over rows if an error occurs as well as when all rows have been read.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="79---not-closing-transient-resources"&gt;79 - Not closing transient resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;HTTP body
&lt;ul&gt;
&lt;li&gt;The response body should be closed to avoid resource leaks (this is done automatically on the server side). This can be done conveniently with &lt;code&gt;defer&lt;/code&gt; function that should call &lt;code&gt;resp.Body.Close()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The body should be closed even if it was not read (e.g., just checking the status code).
&lt;ul&gt;
&lt;li&gt;The body should be read to have a &amp;ldquo;keep-alive&amp;rdquo; connection (&lt;code&gt;io.Discard&lt;/code&gt; is efficient for this purpose).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sql.Rows&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Rows should be closed to release the database connection.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;os.File&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;When closing a file in a &lt;code&gt;defer&lt;/code&gt; function, the error should be sent back to the parent function to be handled in case of error while closing a writable file, for instance.&lt;/li&gt;
&lt;li&gt;If a write should be committed immediately, the file should be flushed before closing it with &lt;code&gt;file.Sync()&lt;/code&gt; (this is a synchronous operation).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="80---forgetting-the-return-statement-after-replying-to-an-http-request"&gt;80 - Forgetting the return statement after replying to an HTTP request&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;http.Error&lt;/code&gt; does not stop the handler&amp;rsquo;s execution.&lt;/li&gt;
&lt;li&gt;After calling &lt;code&gt;http.Error&lt;/code&gt;, the handler should return to stop the execution.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="81---using-the-default-http-client-and-server"&gt;81 - Using the default HTTP client and server&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;HTTP client
&lt;ul&gt;
&lt;li&gt;The default client does not specify any timeouts.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;HTTP server
&lt;ul&gt;
&lt;li&gt;Just like the client, default timeouts should be overridden in production applications to avoid abuse and resource leaks.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="testing"&gt;Testing&lt;/h2&gt;
&lt;h3 id="82---not-categorizing-tests"&gt;82 - Not categorizing tests&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;They should be organized as per the testing pyramid:
&lt;ul&gt;
&lt;li&gt;Unit tests: test a single function or method.&lt;/li&gt;
&lt;li&gt;Integration tests: test the interaction between multiple components.&lt;/li&gt;
&lt;li&gt;End-to-end tests: test the entire system.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;It is not always necessary to run all tests at different stages of a project.&lt;/li&gt;
&lt;li&gt;One can add a build flag such as &lt;code&gt;// go:build integration&lt;/code&gt; to run integration tests only when needed.
&lt;ul&gt;
&lt;li&gt;By default, files without a build flag will be run. Use &lt;code&gt;go test --tags=integration -v .&lt;/code&gt; to run integration tests.&lt;/li&gt;
&lt;li&gt;It is possible to include negation in the build flag, e.g., &lt;code&gt;// go:build !integration&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Build tags apply to the whole file, not individual tests.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Using environment variables may be a better approach than build flags, because one can forget about existing tests that are being ignored and not explicitly flagged as such.
&lt;ul&gt;
&lt;li&gt;Each test can then decide to check for environment variables being set and use &lt;code&gt;t.skip&lt;/code&gt; to skip the test if the environment variable is not set.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;testing.Short()&lt;/code&gt; in a conditional statement to skip long-running tests when running tests with the &lt;code&gt;-short&lt;/code&gt; flag.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="83---not-enabling-the--race-flag"&gt;83 - Not enabling the &lt;code&gt;-race&lt;/code&gt; flag&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;In Go, the race detector is a tool used at runtime to find data races.
&lt;ul&gt;
&lt;li&gt;It is really useful, but brings quite a performance hit (5-10x memory, 2-20x execution time).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Concurrent code should be tested thoroughly to make use of the &lt;code&gt;-race&lt;/code&gt; flag.&lt;/li&gt;
&lt;li&gt;To avoid false positives in data race detections, one can use a loop to run the logic of the test multiple times.&lt;/li&gt;
&lt;li&gt;If needed, &lt;code&gt;// go:build !race&lt;/code&gt; can be used to exclude tests from running with the &lt;code&gt;-race&lt;/code&gt; flag.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="84---not-using-test-execution-modes"&gt;84 - Not using test execution modes&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;t.Parallel&lt;/code&gt; can be used to run tests in parallel.
&lt;ul&gt;
&lt;li&gt;Sequential tests run first, then all parallel tests run at the same time (up to &lt;code&gt;GOMAXPROCS&lt;/code&gt;, unless configured otherwise on the command-line).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;There exists a &lt;code&gt;-shuffle&lt;/code&gt; flag to randomize the order of tests, which isolates tests from each other.
&lt;ul&gt;
&lt;li&gt;Using &lt;code&gt;-v&lt;/code&gt; flag along with &lt;code&gt;-shuffle&lt;/code&gt; will print the seed used to shuffle the tests, which can be useful to reproduce results from a CI environment.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="85---not-using-table-driven-tests"&gt;85 - Not using table-driven tests&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;They are shorter and more readable than traditional tests.&lt;/li&gt;
&lt;li&gt;They make refactoring tests easier.&lt;/li&gt;
&lt;li&gt;They make test function names clearer/shorter.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="86---sleeping-in-unit-tests"&gt;86 - Sleeping in unit tests&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Sleeping in a test can mean the test is flaky, especially when testing concurrent code.&lt;/li&gt;
&lt;li&gt;Implementing a retry strategy is better than using a passive &lt;code&gt;time.Sleep&lt;/code&gt; in a test.
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;testify&lt;/code&gt; package provides an &lt;code&gt;Eventually&lt;/code&gt; function that can be used to retry a test function a number of times.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;If a test can be synchronized, using a channel to receive the value from a goroutine to be tested can lead to deterministic results with no need for a sleep. This strategy can also implement a timeout using a &lt;code&gt;select&lt;/code&gt; with a &lt;code&gt;time.After&lt;/code&gt; case.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="87---not-dealing-with-the-time-api-efficiently"&gt;87 - Not dealing with the time API efficiently&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Do not rely on &lt;code&gt;time.Now&lt;/code&gt; in a function. If it must be tested, the time functionality could be injected as a dependency.&lt;/li&gt;
&lt;li&gt;Even better, a function should allow receiving a &lt;code&gt;time.Time&lt;/code&gt; as an argument, so that the caller can provide the needed value.&lt;/li&gt;
&lt;li&gt;Time should also not be stored in a global variable, as all tests will share the same time, preventing them from running in parallel.&lt;/li&gt;
&lt;li&gt;Whenever possible, testing time should be abstracted away from the code being tested.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="88---not-using-testing-utility-packages"&gt;88 - Not using testing utility packages&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;httptest&lt;/code&gt; package
&lt;ul&gt;
&lt;li&gt;It can be used to test HTTP handlers.&lt;/li&gt;
&lt;li&gt;Instead of spinning up Docker, a fake server can be used to test the HTTP client.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;iotest&lt;/code&gt; package
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;io.Reader&lt;/code&gt; and &lt;code&gt;io.Writer&lt;/code&gt; can be tested with this package.&lt;/li&gt;
&lt;li&gt;It can be used to test edge cases, such as reading a file that is too large or to make sure a reader is resilient against errors (e.g., network error).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="89---writing-inaccurate-benchmarks"&gt;89 - Writing inaccurate benchmarks&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;testing.B&lt;/code&gt; to run benchmarks. Then run &lt;code&gt;go test -bench=.&lt;/code&gt;, optionally adding the flag &lt;code&gt;-benchtime=2s&lt;/code&gt; to run the benchmark for 2 seconds (default is 1 second).&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;b.ResetTimer&lt;/code&gt; after an expensive setup to reset the timer.&lt;/li&gt;
&lt;li&gt;If the expensive call must be done for each iteration in the testing loop, then one can use &lt;code&gt;b.StopTimer&lt;/code&gt; and &lt;code&gt;b.StartTimer&lt;/code&gt; to stop and start the timer, respectively.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;perflock&lt;/code&gt; can be used to lock the CPU frequency to avoid performance fluctuations during benchmarking.&lt;/li&gt;
&lt;li&gt;Micro-benchmarks should be avoided, as they can be misleading. &lt;code&gt;benchstat&lt;/code&gt; can be used to compare benchmarks. For instance, run &lt;code&gt;go test -bench=. -count=10 | tee stats.txt&lt;/code&gt; to save the results to a file, then run &lt;code&gt;benchstat stats.txt&lt;/code&gt; to compare the results.&lt;/li&gt;
&lt;li&gt;Reusing the same variable in a benchmark can lead to incorrect results, as the compiler may optimize the code. To avoid this, use &lt;code&gt;b.N&lt;/code&gt; to create a new variable for each iteration.&lt;/li&gt;
&lt;li&gt;Forcing a benchmark to recreate data for each iteration of a loop may prevent CPU caching from affecting the results.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="90---not-exploring-all-the-go-testing-features"&gt;90 - Not exploring all the Go testing features&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;go test -coverprofile=coverage.out ./...&lt;/code&gt; in combination with &lt;code&gt;go tool cover -html=coverage.out&lt;/code&gt; to generate a coverage report.&lt;/li&gt;
&lt;li&gt;Test exposed behavior by creating a separate package so that unexported elements and internals are not tested.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;testing.T&lt;/code&gt; can be used to test the behavior of a function, while &lt;code&gt;testing.B&lt;/code&gt; can be used to test the performance of a function.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;t.Cleanup&lt;/code&gt; can be used to clean up resources after a test (e.g., close a database connection).&lt;/li&gt;
&lt;li&gt;When multiple cleanup functions are needed, they will be executed in reverse order of registration (LIFO), just like using &lt;code&gt;defer&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;TestMain&lt;/code&gt; can be used to set up and tear down resources for all tests in a package.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="optimizations"&gt;Optimizations&lt;/h2&gt;
&lt;h3 id="91---not-understanding-cpu-caches"&gt;91 - Not understanding CPU caches&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Mechanical sympathy&lt;/em&gt; is about understanding the hardware to write efficient code.&lt;/li&gt;
&lt;li&gt;Most modern CPU architectures have three levels of cache: L1, L2, and L3.&lt;/li&gt;
&lt;li&gt;L2 is about 4 times slower than L1, and L3 is about 10 times slower than L2.&lt;/li&gt;
&lt;li&gt;L3 is a &lt;em&gt;victim cache&lt;/em&gt; containing only data evicted from L2.&lt;/li&gt;
&lt;li&gt;Access to main memory is between 50 and 100 times slower than access to L1 cache.&lt;/li&gt;
&lt;li&gt;A &lt;em&gt;cache line&lt;/em&gt; is the smallest unit of data that can be transferred between the cache and main memory. When first accessible a memory location, it results in a &lt;em&gt;compulsory miss&lt;/em&gt;. Once the cache line is copied to the cache, subsequent accesses to the same memory location and contiguous ones will result in a &lt;em&gt;cache hit&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;A struct of slices can be about 20% faster than a slice of structs, because of &lt;em&gt;spatial locality&lt;/em&gt;. For 16 elements, it may require 2 cache lines instead of 4 for a struct containing fields with slices.&lt;/li&gt;
&lt;li&gt;Data structures affect &lt;em&gt;predictability&lt;/em&gt; at the CPU level.
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Unit stride&lt;/em&gt; is when the CPU can predict the next memory location to access. All values are contiguous in memory.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Constant stride&lt;/em&gt; is when the CPU can predict the next memory location to access (e.g., read every two elements of a slice), but the values are not contiguous in memory.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Non-unit stride&lt;/em&gt; is when the CPU cannot predict the next memory location to access. The values are not contiguous in memory. This would be the case for a linked list or a slice of pointers.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Cache placement policy&lt;/em&gt; works roughly with the principle of &lt;em&gt;least recently used&lt;/em&gt; (pseudo-LRU). When a cache line is full, the least recently used cache line is evicted.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Conflict misses&lt;/em&gt; happen because the cache is partitioned into sets, and two memory locations map to the same set. This can be avoided by aligning data structures to the cache line size.&lt;/li&gt;
&lt;li&gt;A &lt;em&gt;critical stride&lt;/em&gt; accesses memory addresses with the same set index, leading to a &lt;em&gt;conflict miss&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;This is why micro-benchmarking can be misleading: if the production system uses a different cache architecture, the results may be widely different.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="92---writing-concurrent-code-that-leads-to-false-sharing"&gt;92 - Writing concurrent code that leads to false sharing&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;False sharing&lt;/em&gt; is when two threads access different variables that are on the same cache line, and at least one of the goroutines is a writer.&lt;/li&gt;
&lt;li&gt;This causes the cache line to be invalidated.&lt;/li&gt;
&lt;li&gt;One solution is to add &lt;em&gt;padding&lt;/em&gt; to the struct to ensure that the variables are on different cache lines, so that the same cache line is not copied across different logical cores.&lt;/li&gt;
&lt;li&gt;Another approach is to use channels to communicate between goroutines, which will avoid false sharing, instead of having two goroutines share the same struct.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="93---not-taking-into-account-instruction-level-parallelism"&gt;93 - Not taking into account instruction-level parallelism&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Data hazards&lt;/em&gt; occur when an instruction depends on the result of a previous instruction (e.g., read and increment a variable).&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Control hazards&lt;/em&gt; occur when the CPU cannot predict the next instruction to execute (e.g., conditionals).&lt;/li&gt;
&lt;li&gt;Sometimes, introducing a temporary variable can help the CPU predict the next instruction and parallelize the execution.&lt;/li&gt;
&lt;li&gt;One should remain cautious about micro-optimizations, since the Go compiler keeps evolving, and the generated assembly code may change.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="94---not-being-aware-of-data-alignment"&gt;94 - Not being aware of data alignment&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&amp;quot;[&amp;hellip;] a variable&amp;rsquo;s memory address should be a multiple of its own size&amp;quot;&lt;/em&gt;: this is the principle of &lt;em&gt;data alignment&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;A struct size must be a multiple of the &lt;em&gt;word&lt;/em&gt; size (8 bytes on 64-bit systems).&lt;/li&gt;
&lt;li&gt;A struct being an atomic unit, it should be aligned to the word size, as it won&amp;rsquo;t be reorganized by the compiler. The compiler only adds padding to the fields to guarantee data alignment.&lt;/li&gt;
&lt;li&gt;Rule of thumb: organize structs by size, from largest to smallest, to avoid padding. This leads to better spatial locality and cache usage.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="95---not-understanding-stack-vs-heap"&gt;95 - Not understanding stack vs. heap&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Stack is the default memory. LIFO. Stores all local variables for a goroutine.&lt;/li&gt;
&lt;li&gt;Currently, each goroutine initially gets 2 KB of stack space (contiguous memory, to preserve data locality), which can grow up to 1 GB.&lt;/li&gt;
&lt;li&gt;A stack frame is created for each function call, and it is destroyed when the function returns. The stack frames pile up from accessing different functions inside a given goroutine.&lt;/li&gt;
&lt;li&gt;A stack is self-cleaning: it requires no garbage collection. Each goroutine has its own stack.&lt;/li&gt;
&lt;li&gt;Using pointers, slices, and maps will allocate memory on the heap. One reason is that memory addresses from a stack frame coming from a returned function could not be accessed anymore with a stack.&lt;/li&gt;
&lt;li&gt;The memory heap in Go is managed by the garbage collector and is shared among all goroutines. Variables that &lt;em&gt;could&lt;/em&gt; still be referenced after exiting a function are stored on the heap.&lt;/li&gt;
&lt;li&gt;Allocations on the stack are trivial and faster than on the heap. The stack is also more cache-friendly.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Escape analysis&lt;/em&gt; is a compiler optimization that determines whether a variable can be allocated on the stack or the heap.
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;Sharing up&amp;rdquo; escapes to the heap (need a reference from a context that is about to be destroyed).&lt;/li&gt;
&lt;li&gt;&amp;ldquo;Sharing down&amp;rdquo; stays on the stack (no reference to the variable outside the function).&lt;/li&gt;
&lt;li&gt;Global variables are stored on the heap, because they can be shared across goroutines.&lt;/li&gt;
&lt;li&gt;A pointer sent to a channel will escape to the heap.&lt;/li&gt;
&lt;li&gt;A variable referenced by a value sent to a channel.&lt;/li&gt;
&lt;li&gt;When a local variable is too large to fit on the stack.&lt;/li&gt;
&lt;li&gt;When building a program, the &lt;code&gt;-gcflags &amp;quot;-m&amp;quot;&lt;/code&gt; flag can be used to see the escape analysis results.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="96---not-knowing-how-to-reduce-allocations"&gt;96 - Not knowing how to reduce allocations&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;Reader&lt;/code&gt; interface takes in a slice of bytes and returns the number of bytes read and an error. If it had been the other way around, the slice would always escape to the heap.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sync.Pool&lt;/code&gt; can be used to reduce the number of allocations. It is a pool of objects that can be reused. E.g., when writing a slice of bytes to a buffer, the buffer can be reused.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sync.Pool&lt;/code&gt; is thread-safe.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="97---not-relying-on-inlining"&gt;97 - Not relying on inlining&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Mid-stack inlining&lt;/em&gt; is when the compiler inlines a function call that is in the middle of the stack, not at the top (e.g., &lt;code&gt;main&lt;/code&gt; calls &lt;code&gt;foo&lt;/code&gt;, which calls &lt;code&gt;bar&lt;/code&gt;, both functions are simple, so &lt;code&gt;bar&lt;/code&gt; is inlined in &lt;code&gt;foo&lt;/code&gt; and &lt;code&gt;foo&lt;/code&gt; is in turn inlined in &lt;code&gt;main&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Slow vs. fast paths can be optimized by the compiler. The slow path can be extracted to a separate function, which will be inlined in the fast path (&lt;em&gt;&amp;ldquo;fast-path inlining technique&amp;rdquo;&lt;/em&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="98---not-using-go-diagnostics-tooling"&gt;98 - Not using Go diagnostics tooling&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Profiling
&lt;ul&gt;
&lt;li&gt;With profiling, one can see where the program is spending most of its time. &lt;code&gt;pprof&lt;/code&gt; is the Go profiler.&lt;/li&gt;
&lt;li&gt;There are different profiles: CPU (time spent), goroutine (stack traces of ongoing routines), heap (check memory leaks and current allocations), mutex (check time spent in locking calls), block (see where goroutines waits on synchronous operations).&lt;/li&gt;
&lt;li&gt;A profile can be generated while benchmarking: &lt;code&gt;go test -bench=. -cpuprofile profile.out&lt;/code&gt;. This profile can be used with &lt;code&gt;go tool pprof -http=:8080 profile.out&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Heap profiling
&lt;ul&gt;
&lt;li&gt;It&amp;rsquo;s a good idea to force garbage collection before dumping the heap profile to avoid false assumptions. This can be done via the web UI at &lt;code&gt;http://localhost/debug/pprof/heap?gc=1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Snapshots can be compared with &lt;code&gt;go tool pprof -http=:8080 -diff_base &amp;lt;file2&amp;gt; &amp;lt;file1&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Goroutine profiling
&lt;ul&gt;
&lt;li&gt;We can inspect to check for &amp;ldquo;goroutine leaks&amp;rdquo;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Block profiling
&lt;ul&gt;
&lt;li&gt;Useful to check performance affected by blocking calls. Must call &lt;code&gt;runtime.SetBlockProfileRate&lt;/code&gt; to enable it. This profiler stays on until the program ends.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Mutex profiling
&lt;ul&gt;
&lt;li&gt;Useful to check performance affected by mutex locks. Must call &lt;code&gt;runtime.SetMutexProfileFraction&lt;/code&gt; to enable it. This profiler stays on until the program ends.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;A single profiler should be enabled at a time.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Execution tracer
&lt;ul&gt;
&lt;li&gt;Used to check how garbage collection performs, how goroutines are scheduled, and how the scheduler behaves.&lt;/li&gt;
&lt;li&gt;It can be enabled with &lt;code&gt;go test -bench=. -v -trace=trace.out&lt;/code&gt; or by downloading a trace file with &lt;code&gt;/debug/pprof/trace?debug=0&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The granularity of the tracer is per goroutine (unlike CPU profiling, which is per function).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="99---not-understanding-how-the-gc-works"&gt;99 - Not understanding how the GC works&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;debug.FreeOSMemory()&lt;/code&gt; can be used to force the garbage collector to release memory to the OS.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GODEBUG=gctrace=1&lt;/code&gt; can be used to see the garbage collector in action.&lt;/li&gt;
&lt;li&gt;One can force a large allocation of memory with something like &lt;code&gt;var min = make([]byte, 1_000_000_000)&lt;/code&gt; so that the garbage collector will only trigger once the heap reaches twice the size of the allocation, which can reduce the impact on latency if otherwise many garbage collections would be triggered in a short period of time. On most systems, this leads to a &lt;em&gt;lazy allocation&lt;/em&gt; (in the virtual address space). This is useful when the heap peak is known in advance.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="100---not-understanding-the-impacts-of-running-go-in-docker-and-kubernetes"&gt;100 - Not understanding the impacts of running Go in Docker and Kubernetes&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;CPU throttling can occur in Docker and Kubernetes, leading to performance degradation.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GOMAXPROCS&lt;/code&gt; should be set to the number of CPUs available to the container.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="resources-and-references"&gt;Resources and references&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://cs.opensource.google/go/x/website/&amp;#43;/e0d934b4:blog/blog.go;l=32"&gt;&lt;code&gt;init&lt;/code&gt; function of the Go blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.manning.com/books/100-go-mistakes-and-how-to-avoid-them"&gt;100 Go Mistakes and How to Avoid Them&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/teivah/advent-of-code"&gt;Advent of Code solutions by teivah&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/teivah/100-go-mistakes"&gt;GitHub repository of 100 Go Mistakes by teivah&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pubmed.ncbi.nlm.nih.gov/27648988/"&gt;Learning from Errors&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pubmed.ncbi.nlm.nih.gov/22042726/"&gt;Mind your errors: evidence for a neural mechanism linking growth mind-set to adaptive posterror adjustments&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/golang-standards/project-layout"&gt;Project layout&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;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"&gt;Synopsys-Sponsored CISQ Research Estimates Cost of Poor Software Quality in the US $2.08 Trillion in 2020&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://teivah.dev/"&gt;teivah.dev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://engineering.purdue.edu/WukLab/GoStudy-ASPLOS19.pdf"&gt;Understanding Real-World Concurrency Bugs in Go&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded><dc:creator>Sébastien Lavoie</dc:creator><pubDate>Sat, 24 Aug 2024 14:55:00 -0600</pubDate><guid isPermaLink="false">https://www.sglavoie.com/posts/book-summary-100-go-mistakes-and-how-to-avoid-them/</guid><category>learnings</category><category>best practices</category><category>books</category><category>go</category><category>skimming-notes</category></item><item><title>Book summary: Learning Go – An Idiomatic Approach to Real-World Go Programming</title><link>https://www.sglavoie.com/posts/book-summary-learning-go-idiomatic-approach-real-world-go-programming/</link><description>Learning Go is a book that teaches idiomatic Go style and best practices through concrete examples. It covers fundamental features like types and control flow, as well as more advanced topics like concurrency and reflection. The goal is to help readers write clear, readable, robust Go code. I think it succeeded at that!</description><content:encoded>&lt;hr&gt;
&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Go is a modern programming language developed by Google that has gained immense popularity in recent years. It is a statically typed, compiled language that combines aspects of imperative and object-oriented programming. Go aims to provide simplicity, performance, and reliability.&lt;/p&gt;
&lt;p&gt;In his book, Jon provides a comprehensive introduction to Go programming. The book focuses on teaching idiomatic Go code by using concrete examples and focusing on how experienced Go developers structure their code. It covers fundamental language features like primitive types, control structures, and composite types. It also dives into more advanced topics like concurrency through goroutines and channels, writing tests, and using reflection.&lt;/p&gt;
&lt;p&gt;This summary highlights the key takeaways from each chapter. It aims to provide an overview of the core concepts and best practices for writing clear, readable, robust Go code. It&amp;rsquo;s written from the perspective of a developer who has experience with other programming languages like Python, Java, and TypeScript but practically none in Go.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="setting-up-your-go-environment"&gt;Setting Up Your Go Environment&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;golint&lt;/code&gt; to enforce the right coding style of a project.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;go version&lt;/code&gt; to check the version of Go installed.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;go vet&lt;/code&gt; to find errors that may not be detected by the compiler, such as having the wrong number of arguments passed to a &lt;code&gt;Printf&lt;/code&gt; call.&lt;/li&gt;
&lt;li&gt;A common idiom to run multiple commands at once when building a project is to rely on a &lt;code&gt;Makefile&lt;/code&gt; like this:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;makefile&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-makefile" data-lang="makefile"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;.DEFAULT_GOAL&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; build
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; go fmt ./...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;.PHONY&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;lint&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; golint ./...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;.PHONY&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;lint&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;vet&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; go vet ./...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;.PHONY&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;vet&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;vet&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; go build hello.go
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;.PHONY&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;build&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Typing &lt;code&gt;make&lt;/code&gt; will run &lt;code&gt;fmt&lt;/code&gt;, then &lt;code&gt;vet&lt;/code&gt;, then &lt;code&gt;build&lt;/code&gt; since the default task is &lt;code&gt;build&lt;/code&gt;, which requires &lt;code&gt;vet&lt;/code&gt; to have run first, which in turn requires &lt;code&gt;fmt&lt;/code&gt; to have run first, which in turn has no dependency, so &lt;code&gt;fmt&lt;/code&gt; runs and the chain continues.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Testing whether a new version of Go works for existing programs compiled on an older version is straightforward:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;bash&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;go get golang.org/dl/go.1.x.y &lt;span class="c1"&gt;# replace x.y&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;go1.x.y download
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# try out the changes&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;go1.x.y build
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# If all good, remove this secondary version&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;go1.x.y env GOROOT
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/.../.../go1.x.y
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf &lt;span class="k"&gt;$(&lt;/span&gt;go1.x.y env GOROOT&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm &lt;span class="k"&gt;$(&lt;/span&gt;go env GOPATH&lt;span class="k"&gt;)&lt;/span&gt;/bin/go1.x.y
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Install new version as wanted...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;hr&gt;
&lt;h2 id="predeclared-types-and-declarations"&gt;Predeclared Types and Declarations&lt;/h2&gt;
&lt;h2 id="predeclared-types"&gt;Predeclared types&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Zero value
&lt;ul&gt;
&lt;li&gt;Assigned to a variable that is declared with no initial value (doesn&amp;rsquo;t lead to bugs like in C or C++).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Literals
&lt;ul&gt;
&lt;li&gt;These express different bases, such as &lt;code&gt;0b&lt;/code&gt; (binary), &lt;code&gt;0o&lt;/code&gt; (octal) or &lt;code&gt;0x&lt;/code&gt; (hexadecimal). As in other languages like Python or Java, underscores can be used to express large numbers by separating digits (e.g., &lt;code&gt;1_000_000&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Floating point literals look like &lt;code&gt;6.03e23&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Rune literals are represented with single quotes (no double quotes accepted). The most common ones are &lt;code&gt;('\n')&lt;/code&gt;, tab &lt;code&gt;('\t')&lt;/code&gt;, single quote &lt;code&gt;('\'')&lt;/code&gt;, double quote &lt;code&gt;('\&amp;quot;')&lt;/code&gt; and backslash &lt;code&gt;('\\')&lt;/code&gt;. Other bases are supported but should be limited to specific contexts (e.g., bit filters for base two).&lt;/li&gt;
&lt;li&gt;String literals can be written with double quotes, where everything must be escaped.&lt;/li&gt;
&lt;li&gt;Raw string literals use backticks instead of double quotes and can be used to insert any character except a backtick. They support multiline expressions.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Boolean
&lt;ul&gt;
&lt;li&gt;The type is &lt;code&gt;bool&lt;/code&gt; and the default zero value is &lt;code&gt;false&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Numeric types
&lt;ul&gt;
&lt;li&gt;Integers
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;int8&lt;/code&gt; (aliased &lt;code&gt;byte&lt;/code&gt;, which is much more common), &lt;code&gt;int16&lt;/code&gt;, &lt;code&gt;int32&lt;/code&gt;, &lt;code&gt;int64&lt;/code&gt;, &lt;code&gt;uint8&lt;/code&gt;, &lt;code&gt;uint16&lt;/code&gt;, &lt;code&gt;uint32&lt;/code&gt;, &lt;code&gt;uint64&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The zero value is 0.&lt;/li&gt;
&lt;li&gt;Use the minimum size when needed for specific applications.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;int64&lt;/code&gt; and &lt;code&gt;uint64&lt;/code&gt; for library functions (suggested back when generics weren&amp;rsquo;t available).&lt;/li&gt;
&lt;li&gt;Otherwise, just use &lt;code&gt;int&lt;/code&gt;. Other types should be considered a premature optimization until proven otherwise.&lt;/li&gt;
&lt;li&gt;Variables can be modified like so: &lt;code&gt;+=&lt;/code&gt;, &lt;code&gt;-=&lt;/code&gt;, &lt;code&gt;*=&lt;/code&gt;, &lt;code&gt;/=&lt;/code&gt; and &lt;code&gt;%=&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Available comparisons are: &lt;code&gt;==&lt;/code&gt;, &lt;code&gt;!=&lt;/code&gt;, &lt;code&gt;&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;gt;=&lt;/code&gt;, &lt;code&gt;&amp;lt;&lt;/code&gt;, and &lt;code&gt;&amp;lt;=&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Bit manipulations
&lt;ul&gt;
&lt;li&gt;Shifts: &lt;code&gt;&amp;lt;&amp;lt;&lt;/code&gt; (left), &lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt; (right)&lt;/li&gt;
&lt;li&gt;Logical bit masks: &lt;code&gt;&amp;amp;&lt;/code&gt; (&lt;code&gt;AND&lt;/code&gt;), &lt;code&gt;|&lt;/code&gt; (&lt;code&gt;OR&lt;/code&gt;), &lt;code&gt;^&lt;/code&gt; (&lt;code&gt;XOR&lt;/code&gt;), &lt;code&gt;&amp;amp;^&lt;/code&gt; (&lt;code&gt;AND NOT&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;These operators can be used to modify a variable as well: &lt;code&gt;&amp;amp;=&lt;/code&gt;, &lt;code&gt;|=&lt;/code&gt;, &lt;code&gt;^=&lt;/code&gt;, &lt;code&gt;&amp;amp;^=&lt;/code&gt;, &lt;code&gt;&amp;lt;&amp;lt;=&lt;/code&gt;, &lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Floating point types
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;float32&lt;/code&gt;, &lt;code&gt;float64&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The zero value is 0.&lt;/li&gt;
&lt;li&gt;If using a floating point number, opt for &lt;code&gt;float64&lt;/code&gt; unless a profiler shows significant improvement with &lt;code&gt;float32&lt;/code&gt; and the precision is good enough (6-7 decimal places).&lt;/li&gt;
&lt;li&gt;Strict equality (or inequality) should not be done on floating point numbers: check the variance instead (less than epsilon).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Complex types
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;complex64&lt;/code&gt; uses &lt;code&gt;float32&lt;/code&gt; to represent real and imaginary parts, while &lt;code&gt;complex128&lt;/code&gt; uses &lt;code&gt;float64&lt;/code&gt;, using the &lt;code&gt;complex&lt;/code&gt; built-in function and &lt;code&gt;real&lt;/code&gt; and &lt;code&gt;image&lt;/code&gt; functions to extract the relevant parts.&lt;/li&gt;
&lt;li&gt;As with floating point numbers, use the epsilon technique to check for equality.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Strings and runes
&lt;ul&gt;
&lt;li&gt;The zero value is an empty string.&lt;/li&gt;
&lt;li&gt;Strings are immutable.&lt;/li&gt;
&lt;li&gt;Strings can be checked for equality or compared for ordering (&lt;code&gt;&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;gt;=&lt;/code&gt;, &lt;code&gt;&amp;lt;&lt;/code&gt;, or &lt;code&gt;&amp;lt;=&lt;/code&gt;) and can be concatenated with the &lt;code&gt;+&lt;/code&gt; operator.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;rune&lt;/code&gt; type represents a single code point, equivalent to &lt;code&gt;int32&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Explicit type conversion
&lt;ul&gt;
&lt;li&gt;All type conversions are explicit.&lt;/li&gt;
&lt;li&gt;There is no concept of &amp;ldquo;truthiness&amp;rdquo; (e.g., &lt;code&gt;if 2: print(&amp;quot;ok&amp;quot;)&lt;/code&gt; is valid in Python).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="var-vs-"&gt;&lt;code&gt;var&lt;/code&gt; vs. &lt;code&gt;:=&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;var&lt;/code&gt; is more verbose but flexible:&lt;/p&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// because the default type is `int`&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// no value =&amp;gt; it will be the zero value&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// multiple assignments&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// multiple assignments, zero values&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;hi&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// different default types&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Declaration list&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Type inference can be performed within a function:&lt;/p&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// These statements are equivalent&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// invalid syntax outside a function&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Avoid &lt;code&gt;:=&lt;/code&gt; in the following situations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When explicitly initializing a &lt;em&gt;zero value&lt;/em&gt;, like &lt;code&gt;var x int&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;To avoid a &lt;em&gt;type conversion&lt;/em&gt;, by writing &lt;code&gt;var x byte = 8&lt;/code&gt; instead of &lt;code&gt;x := byte(8)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;To avoid &amp;ldquo;&lt;em&gt;shadowing&lt;/em&gt;&amp;rdquo; a variable, as &lt;code&gt;:=&lt;/code&gt; can be used to assign to existing variables. Create new variables with &lt;code&gt;var&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Non-constant package-level variables are a bad idea. If they&amp;rsquo;re unused, they go unnoticed without raising compile-time errors.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="const"&gt;&lt;code&gt;const&lt;/code&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Variables cannot be declared as immutable.&lt;/li&gt;
&lt;li&gt;Constants are a way of giving names to literals.&lt;/li&gt;
&lt;li&gt;Inside a function, it is clear when a variable is being modified.&lt;/li&gt;
&lt;li&gt;If a constant is typed (e.g., &lt;code&gt;const typedVar int = 1&lt;/code&gt;), then it can only be assigned to that type, &lt;code&gt;int&lt;/code&gt; in this case.&lt;/li&gt;
&lt;li&gt;If a constant is untyped (e.g., &lt;code&gt;const untypedVar = 2&lt;/code&gt;), then it can be assigned to suitable numerical types.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="unused-variables"&gt;Unused variables&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Unused declared local variables result in a compile-time error.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="naming-variables-and-constants"&gt;Naming Variables and Constants&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Even though many Unicode characters can be used, they should be avoided to maintain clarity.&lt;/li&gt;
&lt;li&gt;Go uses camelCase.&lt;/li&gt;
&lt;li&gt;The less scope a variable has, the shorter its name should be (&lt;code&gt;k&lt;/code&gt; and &lt;code&gt;v&lt;/code&gt; are accepted for key/value, just like &lt;code&gt;i&lt;/code&gt; and &lt;code&gt;j&lt;/code&gt; to use indices when iterating in loops).&lt;/li&gt;
&lt;li&gt;It is common to use the first letter of a type as the variable name (e.g., &lt;code&gt;i&lt;/code&gt; for integers, &lt;code&gt;f&lt;/code&gt; for floats, &lt;code&gt;b&lt;/code&gt; for boolean). If the code is hard to understand, it&amp;rsquo;s a sign the function is trying to do too much.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="composite-types"&gt;Composite Types&lt;/h2&gt;
&lt;h2 id="arrays"&gt;Arrays&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;They are rarely used directly.&lt;/li&gt;
&lt;li&gt;They can be compared (&lt;code&gt;==&lt;/code&gt; and &lt;code&gt;!=&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Their length is retrieved with the built-in &lt;code&gt;len&lt;/code&gt; function.&lt;/li&gt;
&lt;li&gt;Negative indexing is a compile-time error.&lt;/li&gt;
&lt;li&gt;Out-of-bounds indexing results in a &lt;strong&gt;panic&lt;/strong&gt; at runtime.&lt;/li&gt;
&lt;li&gt;Unless there&amp;rsquo;s a very specific need to use a given size of array (e.g., for a cryptographic library), &lt;em&gt;avoid them&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;They exist basically to &lt;em&gt;provide slices&lt;/em&gt;.
&lt;ul&gt;
&lt;li&gt;There are a few ways of declaring arrays:&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// indicate the size and type&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 3 integers assigned to the zero value&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// array literal&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// values specified&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// equivalent&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// sparse array:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// indicate few values at specific locations&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Get and set values&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="slices"&gt;Slices&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;The zero value for a slice is &lt;code&gt;nil&lt;/code&gt;, which represents the lack of a value for some type. &lt;code&gt;nil&lt;/code&gt; itself has no type.&lt;/li&gt;
&lt;li&gt;The size of the array is not specified, making it a slice: &lt;code&gt;var x = []int{10, 20, 30}&lt;/code&gt;. This is a slice literal.&lt;/li&gt;
&lt;li&gt;Can be used like a sparse array: &lt;code&gt;var x = []int{1, 5: 4, 6, 10: 100, 15}&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Multidimensional arrays can be simulated: &lt;code&gt;var x [][]int&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Reads and assignments are the same as with arrays, using square brackets.&lt;/li&gt;
&lt;li&gt;Slices can be created without assigning initial values: &lt;code&gt;var x []int&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Slices aren&amp;rsquo;t comparable, except to check if it is nil (&lt;code&gt;x == nil&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;They&amp;rsquo;re useful for &lt;em&gt;sequential data&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="len"&gt;&lt;code&gt;len&lt;/code&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;code&gt;nil&lt;/code&gt; slice returns &lt;code&gt;0&lt;/code&gt; (&lt;code&gt;len(x)&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="append"&gt;&lt;code&gt;append&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;It it used to grow slices:&lt;/p&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// returns a slice&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// more than one value&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// append to another slice with `...`&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Similar to the spread operator in JavaScript,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// but it goes after the value to spread&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="capacity"&gt;Capacity&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;It increases automatically as needed. It doubles under 1,024 items, then it increases by at least 25%.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cap&lt;/code&gt; returns the current capacity of the slice.&lt;/li&gt;
&lt;li&gt;It is better when possible to allocate the needed size upfront to avoid resizing the arrays.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="make"&gt;&lt;code&gt;make&lt;/code&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;It can be used to create a slice that already has a capacity specified.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;x := make([]int, 5)&lt;/code&gt;: length and capacity of 5 (all zero values). Using &lt;code&gt;append&lt;/code&gt; here would add new values to the end of the slice, after the zero values!&lt;/li&gt;
&lt;li&gt;&lt;code&gt;x := make([]int, 0, 10)&lt;/code&gt; creates an empty slice with a capacity of 10 and after &lt;code&gt;x = append(x, 5,6,7,8)&lt;/code&gt;, it contains &lt;code&gt;[5 6 7 8]&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="emptying-a-slice"&gt;Emptying a slice&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Available since Go 1.21 with the built-in &lt;code&gt;clear&lt;/code&gt; function.&lt;/li&gt;
&lt;li&gt;This sets all elements of the slice to their zero value.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// [1 2 3 4]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// [0 0 0 0]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;a&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;b&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;c&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// [a b c]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// [ ] (empty strings)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="declaring-a-slice"&gt;Declaring a slice&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Slice literals
&lt;ul&gt;
&lt;li&gt;An empty slice literal declares a slice that is non-nil: &lt;code&gt;var x = []int{}&lt;/code&gt;. This is useful to convert to JSON.&lt;/li&gt;
&lt;li&gt;Useful with some initial values or when the values don&amp;rsquo;t change.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="slicing-slices"&gt;Slicing slices&lt;/h3&gt;
&lt;p&gt;These work with square brackets:&lt;/p&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// [1 2 3 4]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// [1 2]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// [2 3 4]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// [2 3]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[:]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// [1 2 3 4]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="slices-can-share-data"&gt;Slices can share data&lt;/h3&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// These are bidirectional changes!&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// affects `x`, `y` and `z`&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// affects `x` and `y`&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// affects `x` and `z`&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Result:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// x: [10 20 30 4]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// y: [10 20]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// z: [20 30 4]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;code&gt;append&lt;/code&gt; can lead to unintuitive results, overwriting existing values:&lt;/p&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// length 0, capacity 5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// x is now [1 2 3 4]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// [1 2], length 2, capacity 5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// [3 4], length 2, capacity 3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// x is now [1 2 30 40], length 4, capacity 5!&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// y is now [1 2 30 40 50], length 5, capacity 5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// z is now [30 40], length 2, capacity 3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// x is now [1 2 30 40 60], length 5, capacity 5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// y is now [1 2 30 40 60], length 5, capacity 5!&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// z is still [30 40], length 2, capacity 3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// x is now [1 2 30 40 70], length 5, capacity 5!&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// y is now [1 2 30 40 70], length 5, capacity 5!&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// z is now [30 40 70], length 3, capacity 3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;One way to avoid this issue is to use &lt;em&gt;full slice expressions&lt;/em&gt; to indicate the capacity of the sub-slices:&lt;/p&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// take a slice of x, up to index 2, with a capacity of 2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// take a slice of x, from index 2 to 4, with a capacity of 2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// x is still [1 2 3 4], length 4, capacity 5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// y is now [1 2 30 40 50], length 5, capacity 6&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// z is still [3 4], length 2, capacity 2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// x is now [1 2 3 4 60], length 5, capacity 5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// y is still [1 2 30 40 50], length 5, capacity 6&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// z is still [3 4], length 2, capacity 2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// x is still [1 2 3 4 60], length 5, capacity 5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// y is still [1 2 30 40 50], length 5, capacity 6&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// z is now [3 4 70], length 3, capacity 4&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="converting-arrays-to-slices"&gt;Converting Arrays to Slices&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Arrays can be sliced, though memory will be shared as when slicing a slice.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// [5 6 7 8]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// [5 6]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// [7 8]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// [10 6 7 8]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// y and z are now [10 6] and [7 8]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="converting-slices-to-arrays"&gt;Converting Slices to Arrays&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Data in the slice is copied to new memory (slices and arrays remain independent).&lt;/li&gt;
&lt;li&gt;A slice converted into a pointer to an array will share the same underlying data and memory address.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// [1 2 3 4]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// y is a slice, not a copy&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// [0 0 0 0]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// copy(dst, src)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// [10 2 3 4]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// y is now [10 2 3 4]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// z is now [1 2 3 4]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="copy"&gt;&lt;code&gt;copy&lt;/code&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;It creates a slice that is independent from the original slice.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// It can copy the whole slice if the lengths are the same&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// [1 2 3 4]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// [0 0 0 0]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// num=4, copy(dst, src)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// [1 2 3 4] 4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// [1 2 3 4]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// It can copy a subset of the slice&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// [0 0]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// num=2, copy(dst, src)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// [1 2]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// It can copy from a subset from any position&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// [1 2 3 4]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// [0 0]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:])&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// copy(dst, src)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// [3 4]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:])&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// put the last 3 values at the beginning&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// [2 3 4 4], overwriting&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// It also works with arrays&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// slice, [1 2 3 4]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// array, [5 6 7 8]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// [0 0]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;[:])&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// first 2 values of d into y&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// [5 6]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;[:],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// copy x into d&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// [1 2 3 4]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="strings-and-runes-and-bytes"&gt;Strings and Runes and Bytes&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Strings are arrays of bytes.&lt;/li&gt;
&lt;li&gt;Single characters can be extracted from a string with an &lt;em&gt;index expression&lt;/em&gt;:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;hello&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// c is a byte, not a rune&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 104&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;%T\n&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// uint8 (i.e., byte)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Need to be careful with indexing&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Hello 😄&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// could have expected 7, but it&amp;#39;s 10&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;:])&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// He ���: the emoji is 4 bytes long&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="maps"&gt;Maps&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;The built-in map type is a &lt;em&gt;hash map&lt;/em&gt; (implemented as an array).&lt;/li&gt;
&lt;li&gt;The zero value for a map is &lt;code&gt;nil&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Writing to a &lt;code&gt;nil&lt;/code&gt; map results in a runtime panic.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;len&lt;/code&gt; on a map returns the number of key/value pairs.&lt;/li&gt;
&lt;li&gt;Maps are not comparable (but they can check against &lt;code&gt;nil&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;The key must be comparable: it cannot be a slice, map or function.&lt;/li&gt;
&lt;li&gt;Maps are good when the order of the keys doesn&amp;rsquo;t matter: use a slice when it does.&lt;/li&gt;
&lt;li&gt;All the values must be of the same type, but &lt;em&gt;the keys can be of different types&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Avoid using them as input parameters to functions (use a struct instead to be self-documenting).&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;nilMap&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// ^ ^&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// key type value type&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// map literal: length of 0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;myMap&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// allows reads and writes&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Non-empty map&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;reposByOrg&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;][]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;dbeaver&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;dbeaver&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;cloudbeaver&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;team-edition-deploy&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;slidevjs&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;slidev&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;slidev-vscode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;themes&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;ReactiveX&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;RxJava&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;rxjs&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;RxGo&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// comma at the end here too&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// With a default size&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;myValues&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;][]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// length 0, capacity 10, can grow beyond 10&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="reading-and-writing-maps"&gt;Reading and writing maps&lt;/h3&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;reposByOrgStars&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// length 0, can grow, string to integer&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;reposByOrgStars&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;dbeaver&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// write&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;reposByOrgStars&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;slidevjs&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// write&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;reposByOrgStars&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;ReactiveX&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// read, increment, write (0 -&amp;gt; 1)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// reposByOrgStars[&amp;#34;slidevjs&amp;#34;] := 100 // invalid syntax&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="comma-ok-idiom"&gt;Comma Ok idiom&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;One can get the value of a key and a boolean indicating whether the key exists or not:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;reposByOrgStars&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;dbeaver&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 10 true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;reposByOrgStars&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;notfound&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 0 false&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="deleting-from-a-map"&gt;Deleting from a map&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;delete&lt;/code&gt; removes a key/value pair from a map:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reposByOrgStars&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;ReactiveX&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// It is safe to delete a key that doesn&amp;#39;t exist&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reposByOrgStars&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;notfound&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// it returns nothing&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// It is safe to delete a key from a nil map&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;nilMap&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nilMap&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;notfound&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// It is safe to delete a key from an empty map&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;emptyMap&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;emptyMap&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;notfound&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="using-maps-as-sets"&gt;Using maps as sets&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Go doesn&amp;rsquo;t have a built-in set type.&lt;/li&gt;
&lt;li&gt;A map can be used as a set by using the key as the value and the value as a boolean:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;mySet&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;mySet&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;hello&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;mySet&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;world&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;mySet&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;hello&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// no error, but it&amp;#39;s still a set&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;This works because if the value isn&amp;rsquo;t found, the zero value is returned, which is &lt;code&gt;false&lt;/code&gt; for booleans.&lt;/li&gt;
&lt;li&gt;To use operations like &lt;code&gt;union&lt;/code&gt;, &lt;code&gt;intersection&lt;/code&gt; and &lt;code&gt;difference&lt;/code&gt;, the most convenient solution is to use a third-party library.&lt;/li&gt;
&lt;li&gt;Structs can also be used as sets as they&amp;rsquo;re more memory efficient, but more clumsy to use as they make use of the &lt;em&gt;comma ok idiom&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="structs"&gt;Structs&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Good when there is related data that needs to be grouped together.&lt;/li&gt;
&lt;li&gt;They are defined with the &lt;code&gt;type&lt;/code&gt; keyword.&lt;/li&gt;
&lt;li&gt;No commas are needed between fields.&lt;/li&gt;
&lt;li&gt;They can be defined inside or outside of a function. If inside a function, they can only be used inside that function.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;lastName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;u&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// zero value for a struct is all zero values for its fields&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Bob&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lastName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Michigan&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;u&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// {18 Bob Michigan}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Assignments can also be done with a struct literal&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;bob&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// also initializes all fields to zero values&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// With initial values&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;jeremy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;49&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// must match the order of the fields&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Jeremy&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// all fields must be specified&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Stretchy&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// {49 Jeremy Stretchy}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// With this style, fields can be left out:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;otherUser&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// using the field name...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Sweaty&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// cannot indicate other fields without the field name&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// lastName is zero value, i.e., empty string&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Accessing a field:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;jeremy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Jer&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jeremy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Jer&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="anonymous-structs"&gt;Anonymous structs&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;They are useful when a struct is only used in one place.&lt;/li&gt;
&lt;li&gt;Useful when &lt;a href="https://en.wikipedia.org/wiki/Marshalling_%28computer_science%29"&gt;marshalling&lt;/a&gt; and unmarshalling data.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;computer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;operatingSystem&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;chip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;operatingSystem&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;macOS&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;chip&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Apple M2 Ultra&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="comparing-and-converting-structs"&gt;Comparing and converting structs&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Contrary to regular structs, they can be compared.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="blocks-shadows-and-control-structures"&gt;Blocks, Shadows, and Control Structures&lt;/h2&gt;
&lt;h2 id="blocks"&gt;Blocks&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;A block is a place where declarations are made.&lt;/li&gt;
&lt;li&gt;The top-level block is the &lt;em&gt;package&lt;/em&gt; block.&lt;/li&gt;
&lt;li&gt;The import statements are in the &lt;em&gt;file&lt;/em&gt; block.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="shadowing-variables"&gt;Shadowing Variables&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;There is a &amp;ldquo;global&amp;rdquo; block, the &lt;em&gt;universe&lt;/em&gt; block, which contains the built-in functions and types. Careful: those keywords can be shadowed!&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// shadowing&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// x is still 10 here (outer block)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// x is shadowed while y is declared!&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 5 20&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 10&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;shadowing fmt package&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// undefined!&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Linters typically won&amp;rsquo;t catch shadowing, but we can install &lt;code&gt;shadow&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;bash&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;go install golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow@latest&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;And we can make it part of the &lt;code&gt;Makefile&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;makefile&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-makefile" data-lang="makefile"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;lint&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; golint ./...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; shadow ./...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;.PHONY&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;lint&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="if-statements"&gt;&lt;code&gt;if&lt;/code&gt; statements&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;The condition must be a boolean expression.&lt;/li&gt;
&lt;li&gt;The usual flow is &lt;code&gt;if ... {...} else if ... { ... } else { ... }&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;There are no parentheses around the condition.&lt;/li&gt;
&lt;li&gt;Variables can be scoped to the &lt;code&gt;if&lt;/code&gt; statement (they&amp;rsquo;ll be available in &lt;code&gt;else if&lt;/code&gt; and &lt;code&gt;else&lt;/code&gt; blocks as well). Only use that feature to define new variables!&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Intn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;That&amp;#39;s too low&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;That&amp;#39;s too big:&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;That&amp;#39;s a good number:&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// n is not available here!&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="for-loops"&gt;&lt;code&gt;for&lt;/code&gt; loops&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;It is the only looping construct in the language.&lt;/li&gt;
&lt;li&gt;It can be used in four different ways to accomplish all looping needs.&lt;/li&gt;
&lt;li&gt;It uses no parentheses.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="complete-for-statement"&gt;Complete &lt;code&gt;for&lt;/code&gt; statement&lt;/h3&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;The initialization statement is executed once before the loop starts. It must use the &lt;code&gt;:=&lt;/code&gt; operator. It can shadow variables.&lt;/li&gt;
&lt;li&gt;The second statement is the condition. It must be a boolean expression. It is checked before each iteration as well as before the loops starts.&lt;/li&gt;
&lt;li&gt;The third statement is the post statement. It is executed after each iteration. It would usually be used to increment a counter.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="condition-only-for-statement"&gt;Condition-only &lt;code&gt;for&lt;/code&gt; Statement&lt;/h3&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;This is a statement that only has a condition. It is equivalent to a &lt;code&gt;while&lt;/code&gt; loop in other languages.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="infinite-for-statement"&gt;Infinite &lt;code&gt;for&lt;/code&gt; Statement&lt;/h3&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Hello&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;This is a statement that has no condition. It is equivalent to a &lt;code&gt;while true&lt;/code&gt; loop in other languages.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="break-and-continue"&gt;&lt;code&gt;break&lt;/code&gt; and &lt;code&gt;continue&lt;/code&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;There is no &lt;code&gt;do... while&lt;/code&gt; construct as in other languages like C, Java or JavaScript.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;do... while&lt;/code&gt; indicates how to &lt;em&gt;stay&lt;/em&gt; in the loop while &lt;code&gt;for&lt;/code&gt; indicates how to &lt;em&gt;leave&lt;/em&gt; the loop.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;break&lt;/code&gt; exits the loop.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;continue&lt;/code&gt; skips the rest of the loop and goes to the next iteration. Use it to avoid nesting loops.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;break&lt;/code&gt; and &lt;code&gt;continue&lt;/code&gt; can be used with labels to break out of nested loops.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="for-range-loop"&gt;&lt;code&gt;for-range&lt;/code&gt; loop&lt;/h3&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;odds&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;range&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;odds&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Here, &lt;code&gt;i&lt;/code&gt; (&lt;code&gt;0&lt;/code&gt; to &lt;code&gt;4&lt;/code&gt;) is the index of the iterator construct and &lt;code&gt;v&lt;/code&gt; (&lt;code&gt;1, 3 ... 9&lt;/code&gt;) is the value.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;i&lt;/code&gt; is usually used for arrays, slices and strings, while &lt;code&gt;k&lt;/code&gt; is used for maps.&lt;/li&gt;
&lt;li&gt;As in other languages like Python, use an underscore (&lt;code&gt;_&lt;/code&gt;) to ignore a value. The index or key can be ignored this way.&lt;/li&gt;
&lt;li&gt;If the key is needed but not the value, leave the value out: &lt;code&gt;for k := range myMap { ... }&lt;/code&gt;. This is useful when using a map as a set.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="iterating-over-maps"&gt;Iterating over maps&lt;/h4&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;a&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;c&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;b&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Loop&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;range&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// order will differ&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// will be in ascending order to help with debugging&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;For security reasons (hash DoS), the order of the keys is randomized. If the order is important, use a slice of keys instead.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="iterating-over-strings"&gt;Iterating over strings&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Go iterates over the Unicode code points (runes), not the bytes.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;samples&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;hello&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;worl∂!&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;sample&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;range&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;samples&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;range&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;sample&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;/*
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;Output:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;0 104 h // index, rune, string(rune)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;1 101 e
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;2 108 l
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;3 108 l
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;4 111 o
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; // first string is 5 runes long
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;0 119 w
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;1 111 o
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;2 114 r
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;3 108 l
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;4 8706 ∂ // this is a single rune: it occupies 3 bytes
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;7 33 ! // index 7! The second string is 8 runes long
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;*/&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h4 id="for-range-value-is-a-copy"&gt;&lt;code&gt;for-range&lt;/code&gt; value is a copy&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Modifying the value variable doesn&amp;rsquo;t change the original value.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;break&lt;/code&gt; and &lt;code&gt;continue&lt;/code&gt; are also available in this form.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;odds&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;range&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;odds&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;odds&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// [1 3 5 7 9]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="for-loop-labels"&gt;&lt;code&gt;for&lt;/code&gt; loop labels&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;While their use is rare, they can be used to break out of nested loops.&lt;/li&gt;
&lt;li&gt;The label is indented to the same level as the containing block.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;samples&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;hello&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;worl∂!&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;outer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;sample&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;range&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;samples&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;range&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;sample&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;&amp;#39;l&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;outer&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;/* Output:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;0 104 h
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;1 101 e
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;2 108 l
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;0 119 w
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;1 111 o
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;2 114 r
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;3 108 l
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;*/&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This code will skip the remaining letters of both words once the first &lt;code&gt;l&lt;/code&gt; is printed out for each one.&lt;/p&gt;
&lt;h3 id="the-right-for-statement"&gt;The right &lt;code&gt;for&lt;/code&gt; statement&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;for-range&lt;/code&gt; is the proper way to iterate over strings to get runes.&lt;/li&gt;
&lt;li&gt;A complete &lt;code&gt;for&lt;/code&gt; statement is good when not iterating through all the items in a collection (except for strings since runes aren&amp;rsquo;t necessarily one byte long).&lt;/li&gt;
&lt;li&gt;The condition-only &lt;code&gt;for&lt;/code&gt; statement is used to replace &lt;code&gt;while&lt;/code&gt; loops.&lt;/li&gt;
&lt;li&gt;Infinite loops can simulate a &lt;code&gt;do... while&lt;/code&gt; construct and can be used to create the iterator pattern.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="expression-switch-statements"&gt;Expression &lt;code&gt;switch&lt;/code&gt; statements&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;They don&amp;rsquo;t use parentheses.&lt;/li&gt;
&lt;li&gt;Used to check for equality.&lt;/li&gt;
&lt;li&gt;Scoped variables can be declared (e.g., &lt;code&gt;word&lt;/code&gt; is scoped to all cases).&lt;/li&gt;
&lt;li&gt;All cases are part of the same block (only the switch statement itself is a block surrounded by braces).&lt;/li&gt;
&lt;li&gt;No need for &lt;code&gt;break&lt;/code&gt; statements. It can be used, but may indicate a code smell.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;break&lt;/code&gt; can be useful if the &lt;code&gt;switch&lt;/code&gt; statement is inside a loop.&lt;/li&gt;
&lt;li&gt;There is a &lt;code&gt;fallthrough&lt;/code&gt; keyword to go to the next case (&lt;em&gt;not recommended&lt;/em&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;words&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Go&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Ada&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;COBOL&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;C++&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Python&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Clojure&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;WebAssembly&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;word&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;range&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;words&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;switch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;word&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// catches multiple matches&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;word&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;is a short name!&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Go, Ada, C++&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;wordLen&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;word&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;word&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;is the right length:&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;wordLen&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// COBOL&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// empty case, nothing happens: Python, Clojure&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;word&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;is a long name!&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// WebAssembly&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Inside a loop&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// label&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;switch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;is even&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;is divisible by 3 but not 2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;exit the loop!&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;loop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// break out of the loop, not just the switch statement&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;is boring&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="blank-switch-statements"&gt;Blank &lt;code&gt;switch&lt;/code&gt; statements&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Instead of checking for equality, they check for any boolean comparison.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;switch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;is even&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;is large&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Got it!&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// this is the one that will be executed&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Not it...&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="if-or-switch"&gt;&lt;code&gt;if&lt;/code&gt; or &lt;code&gt;switch&lt;/code&gt;?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;switch&lt;/code&gt; should be used when there is some relationship between comparable elements. It is more concise and makes the comparisons more obvious.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="goto"&gt;&lt;code&gt;goto&lt;/code&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;It should generally be avoided.&lt;/li&gt;
&lt;li&gt;It can be used to replace boolean flags, such as in &lt;a href="https://cs.opensource.google/go/go/&amp;#43;/refs/tags/go1.21.2:src/strconv/atof.go"&gt;this non-trivial example&lt;/a&gt; from the standard library.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="functions"&gt;Functions&lt;/h2&gt;
&lt;h2 id="declaring-and-calling-them"&gt;Declaring and calling them&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Go has no classes, but it has methods (see &lt;a href="#types-methods-and-interfaces"&gt;chapter 7&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;Types are mandatory.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;return&lt;/code&gt; keyword is mandatory (except for &lt;code&gt;main&lt;/code&gt;) if the function has a return type.&lt;/li&gt;
&lt;li&gt;Nothing goes between the input parameters and the start of the block if there&amp;rsquo;s no return type.&lt;/li&gt;
&lt;li&gt;Go has no named or optional input parameters: you can pass structs instead. In practice, that probably means the function is trying to do too much if you need this feature.&lt;/li&gt;
&lt;li&gt;Go supports variadic parameters (e.g., the &lt;code&gt;fmt.Println&lt;/code&gt; function) with &lt;code&gt;...&lt;/code&gt; right before the type: they are used as a slice inside the function.&lt;/li&gt;
&lt;li&gt;Functions can return multiple values. They must all be returned, comma-separated. Unlike Python which uses tuples, Go uses the comma to separate the individual values.&lt;/li&gt;
&lt;li&gt;The error is always the last parameter a function will return. If no error occurred, it will be &lt;code&gt;nil&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Indicate ignored values (possibly all) with an underscore. A notable exception is &lt;code&gt;fmt.Println&lt;/code&gt; which returns two values that aren&amp;rsquo;t usually used.&lt;/li&gt;
&lt;li&gt;Named values can be returned. They make shadowing possible and should be used sparingly.&lt;/li&gt;
&lt;li&gt;Blank returns can be returned with named values, but they make it harder to understand how data flows.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;div&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;numerator&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;denominator&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// ^ ^ ^ ^&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// | input parameter | return type&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Function name parameter type&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;denominator&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;numerator&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;denominator&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// The following is equivalent when the types are the same&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// func div(numerator, denominator int) int ...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// variadic parameter&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;addTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;base&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;vals&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;out&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;vals&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;range&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;vals&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;out&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;out&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;base&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;out&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// fmt.Println(addTo(1, 2, 3, 4))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// a := []int{4, 3}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// fmt.Println(addTo(3, a...))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// fmt.Println(addTo(3, []int{4, 5}...))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// named return values&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;divAndRemainder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;numerator&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;denominator&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;remainder&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="functions-are-values"&gt;Functions are values&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Functions can be defined as types, e.g., &lt;code&gt;type aFuncType func(int, int) int&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Anonymous functions can be defined inside other functions and called immediately (IIFE). This comes in handy when using &lt;a href="#defer"&gt;&lt;code&gt;defer&lt;/code&gt;&lt;/a&gt; and &lt;a href="#concurrency-in-go"&gt;Goroutines&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="closures"&gt;Closures&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Closures are used to create functions that have access to variables that are outside of their scope.&lt;/li&gt;
&lt;li&gt;Functions can be passed as parameters to other functions.&lt;/li&gt;
&lt;li&gt;Functions can return functions.&lt;/li&gt;
&lt;li&gt;They are useful with &lt;code&gt;sort.Search&lt;/code&gt; and &lt;code&gt;sort.Slice&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;An example of closure is with the &lt;code&gt;sort.Slice&lt;/code&gt; function:&lt;/p&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;sort&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Person&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;FirstName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;LastName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Age&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;HasPet&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;people&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="nx"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Pat&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Patterson&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;37&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Tracy&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Bobbert&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;23&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Fred&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Fredson&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Bob&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Tracier&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Alice&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Anderson&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;people&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// `people` is captured by the closure&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;people&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// If one person has a pet and the other doesn&amp;#39;t,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// prioritize the one with the pet.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;people&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;HasPet&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;people&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;HasPet&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;people&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;HasPet&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// If both have pets, sort by LastName.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;people&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;HasPet&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;people&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;HasPet&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;people&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;LastName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;people&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;LastName&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Otherwise, sort by age in ascending order.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;people&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;Age&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;people&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;Age&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;people&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// This returns:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// - People that have pets first&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// - If both have pets, sort by last name in ascending order&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// - If neither have pets, sort by age in ascending order&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Unsorted:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Pat&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Patterson&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;37&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Tracy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Bobbert&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;23&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Fred&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Fredson&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Bob&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Tracier&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Alice&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Anderson&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Sorted:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Alice&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Anderson&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Fred&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Fredson&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Pat&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Patterson&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;37&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Bob&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Tracier&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Tracy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Bobbert&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;23&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;A function that returns a function:&lt;/p&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;withTwo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;getResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;withThree&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;getResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;i=&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;withTwo (2 + i):&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;withTwo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;withThree (3 + i):&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;withThree&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;getResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initialValue&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;subsequent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;initialValue&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;subsequent&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Output:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// i= 0 withTwo (2 + i): 2 withThree (3 + i): 3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// i= 1 withTwo (2 + i): 3 withThree (3 + i): 4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// i= 2 withTwo (2 + i): 4 withThree (3 + i): 5&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="defer"&gt;&lt;code&gt;defer&lt;/code&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;This is used to perform the cleanup code, such as closing a file, after a function has returned. This is similar to the &lt;code&gt;finally&lt;/code&gt; block in Java or Python but it executes at the very end of the function, not as part of a &lt;code&gt;try...except&lt;/code&gt; block.&lt;/li&gt;
&lt;li&gt;It delays the execution of a function until the surrounding function returns.&lt;/li&gt;
&lt;li&gt;They run in LIFO (last in, first out) order.&lt;/li&gt;
&lt;li&gt;The code that runs after &lt;code&gt;defer&lt;/code&gt; is literally the last thing that runs before the function returns, so what is put there is immediately &amp;ldquo;called&amp;rdquo; (e.g., &lt;code&gt;defer close()&lt;/code&gt;) but will run until later.&lt;/li&gt;
&lt;li&gt;It helps reduce depth of nesting, which, along with &amp;ldquo;lack of structure&amp;rdquo;, are two of the most important factors that contribute to code complexity (see &lt;a href="https://link.springer.com/article/10.1007/s10664-017-9508-2"&gt;this paper&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="go-is-call-by-value"&gt;Go is &amp;ldquo;call by value&amp;rdquo;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Go always makes a copy of the value before passing it to a function.&lt;/li&gt;
&lt;li&gt;Maps and slices behave differently because they are implemented with pointers.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="pointers"&gt;Pointers&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;A pointer is a variable that holds the address of a value in memory&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;The zero value of a pointer is &lt;code&gt;nil&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;amp;&lt;/code&gt; is the &lt;em&gt;address-of operator&lt;/em&gt;. It goes before the variable name to get its address.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;*&lt;/code&gt; is the &lt;em&gt;indirection operator&lt;/em&gt; (dereference). It goes before a pointer to get the value it points to.&lt;/li&gt;
&lt;li&gt;Dereferencing a &lt;code&gt;nil&lt;/code&gt; pointer will result in a runtime panic.&lt;/li&gt;
&lt;li&gt;Types with an &lt;code&gt;*&lt;/code&gt; are pointers to that type (&amp;ldquo;pointer type&amp;rdquo;).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;new&lt;/code&gt; is a built-in function that allocates memory for a type and returns a pointer to it.&lt;/li&gt;
&lt;li&gt;To turn a constant into a pointer, use a helper function that takes a value and returns a pointer to it.&lt;/li&gt;
&lt;li&gt;A pointer is used to indicate that a parameter is mutable, i.e., that the function can modify the original value.&lt;/li&gt;
&lt;li&gt;To update the value of a pointer inside a function, dereference it and assign it a new value.&lt;/li&gt;
&lt;li&gt;Value types should be preferred when returning from functions.&lt;/li&gt;
&lt;li&gt;Use a pointer as a return type when there is a need to return a modified data structure or when the data being passed around is very large (at least 1 MB).&lt;/li&gt;
&lt;li&gt;Slices can be used as buffers when iterating over files to avoid allocating memory in each iteration of the loop.&lt;/li&gt;
&lt;li&gt;The garbage collector will free memory that is no longer used. Go favors low latency over high throughput.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 10 0xc0000b4008&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 0xc0000b4008 10&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// The zero value of a pointer is nil&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// nil&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Dereferencing a nil pointer will result in a runtime panic&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// fmt.Println(*z) // panic: runtime error: invalid memory address or nil pointer dereference&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// new allocates memory for a type and returns a pointer to it&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 0xc0000b4010&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// To turn a constant into a pointer, use a helper function that takes a value&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// and returns a pointer to it&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;intPtr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;intPtr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// A pointer is used to indicate that a parameter is mutable&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;addOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;addOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 11&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// To update the value of a pointer inside a function, dereference it and assign it a new value&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;updatePointer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;updatePointer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;hr&gt;
&lt;h2 id="types-methods-and-interfaces"&gt;Types, Methods, and Interfaces&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Types can be declared at any level, including at the package level.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="methods"&gt;Methods&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Method names cannot be overloaded.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Person&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;FirstName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;LastName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Age&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;String&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// ^&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// p is a receiver of the String method&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;%s %s, age %d&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FirstName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;LastName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Age&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Domi&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Noes&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;String&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Domi Noes, age 42&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="pointer-receivers-and-value-receivers"&gt;Pointer Receivers and Value Receivers&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Use a &lt;em&gt;pointer receiver&lt;/em&gt; when the method needs to modify the receiver.&lt;/li&gt;
&lt;li&gt;Use a &lt;em&gt;pointer receiver&lt;/em&gt; when &lt;code&gt;nil&lt;/code&gt; must be handled.&lt;/li&gt;
&lt;li&gt;A &lt;em&gt;value receiver&lt;/em&gt; is used when the method doesn&amp;rsquo;t need to modify the receiver.&lt;/li&gt;
&lt;li&gt;If a type has a pointer receiver, all methods should have pointer receivers for consistency.&lt;/li&gt;
&lt;li&gt;Usually, there&amp;rsquo;s no need for getters and setters when using structs: just use the fields directly.&lt;/li&gt;
&lt;li&gt;Pointer receiver methods should check for &lt;code&gt;nil&lt;/code&gt; values.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="methods-are-also-functions"&gt;Methods are also functions&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;We can use a &lt;em&gt;method value&lt;/em&gt; to turn a method into a function.&lt;/li&gt;
&lt;li&gt;A &lt;em&gt;method expression&lt;/em&gt; is used to turn a method into a function that takes the receiver as the first parameter.&lt;/li&gt;
&lt;li&gt;They can be use for dependency injection.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Using a method value&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Domi&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Noes&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// using an instance of the struct&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;f&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Domi Noes, age 42&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Using a method expression&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Domi&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Noes&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// using the type itself&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Domi Noes, age 42&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="functions-vs-methods"&gt;Functions vs. methods&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Use a function when there is no need to modify the receiver.&lt;/li&gt;
&lt;li&gt;Use a method with a struct receiver when there is a need to modify data at runtime.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="type-declarations-are-not-inheritance"&gt;Type declarations are not inheritance&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Declaring a type based on another type is not inheritance: there is no hierarchy.&lt;/li&gt;
&lt;li&gt;Type conversion is used to convert a value from one type to another.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="types-serve-as-executable-documentation"&gt;Types serve as executable documentation&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;They can be used to make code more readable and self-documenting.&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;Percentage&lt;/code&gt; type can be used to make it clear what a value is instead of an &lt;code&gt;int&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="use-iota-for-enumeration-sparingly"&gt;Use iota for enumeration (sparingly)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Go does not have an enumeration type.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;iota&lt;/code&gt; is a built-in constant generator that starts at &lt;code&gt;0&lt;/code&gt; and increments by &lt;code&gt;1&lt;/code&gt; for each subsequent constant.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;iota&lt;/code&gt; can be used to create a set of constants that are related to each other.&lt;/li&gt;
&lt;li&gt;It should be used for &amp;ldquo;internal&amp;rdquo; purposes only, when the constants are referred to by name &amp;ndash; not by value.&lt;/li&gt;
&lt;li&gt;It is useful to differentiate between sets of values, not to rely explicitly on the values themselves.&lt;/li&gt;
&lt;li&gt;If the first value in the constant block (with value &lt;code&gt;0&lt;/code&gt;) is not really initialized or the value &lt;code&gt;0&lt;/code&gt; does not make sense, it can be named with an &lt;code&gt;_&lt;/code&gt; to skip &lt;code&gt;0&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Color&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Red&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Color&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;iota&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Green&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Blue&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Red&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Green&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Blue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 0 1 2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="embedding-for-composition"&gt;Embedding for composition&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Types can be embedded to encourage composition.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Person&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;FirstName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;LastName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Age&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Employee&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Person&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// embedded field&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;EmployeeID&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Employee&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;FirstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Domi&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;LastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Noes&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;EmployeeID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;12345&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FirstName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;LastName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Age&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;EmployeeID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Domi Noes 42 12345&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="interfaces"&gt;Interfaces&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Interfaces are declared as a type with the &lt;code&gt;interface&lt;/code&gt; keyword.&lt;/li&gt;
&lt;li&gt;The methods defined in an interface are the methods that a type must implement to be considered an implementation of that interface: this is referred to as the &lt;em&gt;method set&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;They can be declared in any block.&lt;/li&gt;
&lt;li&gt;They usually end with &lt;code&gt;er&lt;/code&gt; (e.g., &lt;code&gt;Stringer&lt;/code&gt;, &lt;code&gt;Reader&lt;/code&gt;, &lt;code&gt;Writer&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;They are implemented implicitly.&lt;/li&gt;
&lt;li&gt;Go is a blend of duck typing (e.g., dynamic behavior in Python) and structural typing (Java interfaces).&lt;/li&gt;
&lt;li&gt;Use built-in interfaces from the standard library as much as possible.&lt;/li&gt;
&lt;li&gt;Just like structs, interfaces can be embedded.&lt;/li&gt;
&lt;li&gt;Interfaces are the only abstract type in Go.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Switching between the logic providers is as simple as changing the type of the L field.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;LogicProvider&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;LogicProvider2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;LogicProvider2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;LogicProvider2: Process&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;LogicProvider2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Rework&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;LogicProvider&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;LogicProvider&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Rework&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;LogicProvider1: Rework&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Logic&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;interface&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Rework&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Client&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;L&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Logic&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Program&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;data&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;L&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;L&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Rework&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;c1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;L&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;LogicProvider&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;c1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Program&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;c2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;L&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;LogicProvider2&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;c2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Program&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Output:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// LogicProvider1: Rework&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// LogicProvider2: Process&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="take-interfaces-and-return-structs"&gt;Take interfaces and return structs&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Returning interfaces increases coupling.&lt;/li&gt;
&lt;li&gt;It is better to return structs and take interfaces as parameters.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="empty-interfaces"&gt;Empty interfaces&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;If an interface is &lt;code&gt;nil&lt;/code&gt;, invoking a method on it will result in a runtime panic.&lt;/li&gt;
&lt;li&gt;An empty interface matches any type, because it requires implementing no methods.&lt;/li&gt;
&lt;li&gt;They can be used when receiving data from an external source (e.g., a database or JSON) and the type is unknown.&lt;/li&gt;
&lt;li&gt;Using &lt;code&gt;interface{}&lt;/code&gt; is a code smell: it should be used sparingly.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="type-assertions-and-type-switches"&gt;Type assertions and type switches&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Use the &lt;em&gt;comma ok&lt;/em&gt; idiom to avoid a type assertion from panicking.&lt;/li&gt;
&lt;li&gt;Type assertions are checked at runtime.&lt;/li&gt;
&lt;li&gt;Type conversions are checked at compile time.&lt;/li&gt;
&lt;li&gt;A type switch is used to check the type of an interface.&lt;/li&gt;
&lt;li&gt;In the case of errors, use &lt;code&gt;errors.Is&lt;/code&gt; and &lt;code&gt;errors.As&lt;/code&gt; to test for specific errors.&lt;/li&gt;
&lt;li&gt;Add a &lt;code&gt;default&lt;/code&gt; case to switch statements to catch unexpected types.&lt;/li&gt;
&lt;li&gt;It can be safer to keep interfaces unexported.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;v1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ok1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ok1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 42 true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;v2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ok2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ok2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// &amp;#34;&amp;#34; false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// type switch&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;switch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.(&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;int&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// int 42&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;float64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;float32&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// check both at once&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;float&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;unknown&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// type assertion using optional interface&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.(&lt;/span&gt;&lt;span class="nx"&gt;MySpecificInterface&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// myInterface satisfies MySpecificInterface&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SpecificMethod&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="function-types-are-a-bridge-to-interfaces"&gt;Function types are a bridge to interfaces&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Functions can implement interfaces.&lt;/li&gt;
&lt;li&gt;Go uses this to implement the &lt;code&gt;http.Handler&lt;/code&gt; interface.&lt;/li&gt;
&lt;li&gt;Small interfaces are encouraged.&lt;/li&gt;
&lt;li&gt;If a function can depend on many other functions, it is better to use a struct with methods.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;HandlerFunc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ResponseWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;HandlerFunc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;ServeHTTP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;w&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ResponseWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;/&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;HandlerFunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;w&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ResponseWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Fprintln&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Hello, world!&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ListenAndServe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;:8080&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;An actual, basic HTTP server:&lt;/p&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;net/http&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;HandlerFunc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ResponseWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;HandlerFunc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;ServeHTTP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;w&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ResponseWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;/&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;HandlerFunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;w&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ResponseWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Fprintln&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Hello, world!&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ListenAndServe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;:8080&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="implicit-interfaces-make-dependency-injection-easier"&gt;Implicit Interfaces Make Dependency Injection Easier&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;[&amp;hellip;] &lt;em&gt;code should explicitly specify the functionality it needs to perform its task&lt;/em&gt;&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;If a type has methods that match an interface&amp;rsquo;s signature, it implicitly satisfies that interface.&lt;/li&gt;
&lt;li&gt;Go&amp;rsquo;s implicit interfaces make dependency injection easier.&lt;/li&gt;
&lt;li&gt;Interfaces are used to decouple code.&lt;/li&gt;
&lt;li&gt;The client&amp;rsquo;s code should not be responsible for creating the dependencies it needs.&lt;/li&gt;
&lt;li&gt;The client&amp;rsquo;s code defines the interfaces and can customize the method set it needs.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here is an example of an implicit interface:&lt;/p&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Talker&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;interface&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Say&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Dog implicitly implements the Talker interface&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Dog&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Say&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Woof!&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Speak&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Talker&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Say&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Speak&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Woof!&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;And an example demonstrating dependency injection:&lt;/p&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Logger is an implicit interface with a Log method&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Logger&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;interface&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// SimpleLogger implicitly satisfies Logger by implementing Log&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;SimpleLogger&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;SimpleLogger&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// AdvancedLogger implicitly satisfies Logger by implementing Log&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;AdvancedLogger&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;al&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;AdvancedLogger&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;ADVANCED: &amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// CompositeLogger combines SimpleLogger and AdvancedLogger&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Again, it implicitly satisfies Logger by implementing Log&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;CompositeLogger&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;loggers&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="nx"&gt;Logger&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Log messages with multiple loggers&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;CompositeLogger&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;logger&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;range&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;cl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;loggers&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;[CompositeLogger] &amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Greeter contains logic to greet&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Greeter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;logger&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Logger&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Logger is injected&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// NewGreeter injects dependencies and returns a new Greeter&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;NewGreeter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;l&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Logger&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Greeter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Greeter&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;l&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Greet uses the Logger to log a greeting&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;g&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Greeter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Greet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Hello, dependency injection and implicit interface!&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;logger1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;SimpleLogger&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Create Logger&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;greeter1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;NewGreeter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;logger1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Inject Logger into Greeter&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;greeter1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Greet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Use Greeter&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Logs:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Hello, dependency injection and implicit interface!&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;logger2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;AdvancedLogger&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Create Logger&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;greeter2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;NewGreeter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;logger2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Inject Logger into Greeter&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;greeter2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Greet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Use Greeter&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Logs:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// ADVANCED: Hello, dependency injection and implicit interface!&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;logger3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;CompositeLogger&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;loggers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="nx"&gt;Logger&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;SimpleLogger&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;AdvancedLogger&lt;/span&gt;&lt;span class="p"&gt;{}}}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;greeter3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;NewGreeter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;logger3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Inject CompositeLogger into Greeter&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;greeter3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Greet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Use Greeter&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Logs:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// [CompositeLogger] Hello, dependency injection and implicit interface!&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// ADVANCED: [CompositeLogger] Hello, dependency injection and implicit interface!&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;hr&gt;
&lt;h2 id="generics"&gt;Generics&lt;/h2&gt;
&lt;h2 id="generics-reduce-repetitive-code-and-increase-type-safety"&gt;Generics Reduce Repetitive Code and Increase Type Safety&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Generics are &amp;ldquo;type parameters&amp;rdquo; that allow one to write functions and data structures that can work with any type.&lt;/li&gt;
&lt;li&gt;They reduce repetitive code and increase type safety.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="generic-functions-abstract-algorithms"&gt;Generic Functions Abstract Algorithms&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Generic functions can be used to abstract algorithms.&lt;/li&gt;
&lt;li&gt;They can be used to write functions that work with any type.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Max returns the maximum of two values&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Max&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;any&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="generics-and-interfaces"&gt;Generics and interfaces&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Generics can be used with interfaces.&lt;/li&gt;
&lt;li&gt;They can be used to write functions that work with any type that satisfies an interface.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Stringer is an interface with a String method&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Stringer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;interface&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;String&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Print calls the String method on a value that satisfies the Stringer interface&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Stringer&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;String&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;hr&gt;
&lt;h2 id="errors"&gt;Errors&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Go does not have exceptions&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Errors are values.&lt;/li&gt;
&lt;li&gt;They are the last return value of a function (by convention).&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;error&lt;/code&gt; interface is defined in the standard library.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;errors&lt;/code&gt; package is used to create errors.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;fmt&lt;/code&gt; package is used to print errors.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;errors.Is&lt;/code&gt; function is used to check for specific errors.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;errors.As&lt;/code&gt; function is used to check for specific errors and get the underlying error.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;errors.Unwrap&lt;/code&gt; function is used to get the underlying error, but &lt;code&gt;errors.Is&lt;/code&gt; and &lt;code&gt;errors.As&lt;/code&gt; are more commonly used for this.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;errors.New&lt;/code&gt; function is used to create errors.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;errors.Errorf&lt;/code&gt; function is used to create errors with formatting.&lt;/li&gt;
&lt;li&gt;When a function returns an error, it is expected that the caller will check for it.&lt;/li&gt;
&lt;li&gt;If a function does not return an error, its value will be &lt;code&gt;nil&lt;/code&gt;, because it is the zero value for interfaces.&lt;/li&gt;
&lt;li&gt;Error messages should not be capitalized or end with punctuation, nor contain newline.&lt;/li&gt;
&lt;li&gt;Because all values must be read, errors cannot be ignored implicitly.&lt;/li&gt;
&lt;li&gt;Because the main code is unindented and the error handling code is indented, the code&amp;rsquo;s purpose is easier to follow.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="sentinel-errors"&gt;Sentinel errors&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Sentinel errors are errors that are predefined and can be checked for equality.&lt;/li&gt;
&lt;li&gt;They are defined at the package level.&lt;/li&gt;
&lt;li&gt;They start with &lt;code&gt;Err&lt;/code&gt; (except for &lt;code&gt;io.EOF&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;They should be treated as read-only.&lt;/li&gt;
&lt;li&gt;They are used to indicate it is not possible to continue processing (e.g., &lt;code&gt;ErrFormat&lt;/code&gt; for ZIP files).&lt;/li&gt;
&lt;li&gt;Whenever possible, use existing sentinel errors from the standard library.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="wrapping-errors"&gt;Wrapping errors&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;To give additional context to an error, wrap it with &lt;code&gt;fmt.Errorf&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;A series of errors can be wrapped with &lt;code&gt;fmt.Errorf&lt;/code&gt; and &lt;code&gt;errors.Unwrap&lt;/code&gt;: these are called &lt;em&gt;error chains&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;If context is not required, a brand new error can be created with &lt;code&gt;errors.New&lt;/code&gt; or &lt;code&gt;errors.Errorf&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;%v&lt;/code&gt; verb can be used to print the error chain without wrapping the error (e.g., &lt;code&gt;fmt.Errorf(&amp;quot;internal failure: %v&amp;quot;, err)&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="is-and-as"&gt;&lt;code&gt;Is&lt;/code&gt; and &lt;code&gt;As&lt;/code&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;errors.Is&lt;/code&gt; to check for specific errors.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;errors.As&lt;/code&gt; to check for specific errors and get the underlying error.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;errors.As&lt;/code&gt; can take as the second parameter a pointer to a variable of the type of the error we are looking for, but just as well it can take a pointer to an interface.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="wrapping-errors-with-defer"&gt;Wrapping Errors with defer&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Using named return values and &lt;code&gt;defer&lt;/code&gt; can make error handling easier because the error can be formatted only once at the end of the function.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="panic-and-recover"&gt;Panic and recover&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;panic&lt;/strong&gt; is used to indicate that the program cannot continue (e.g., out of memory error or trying to read beyond the end of a slice).&lt;/li&gt;
&lt;li&gt;When a panic occurs, the program stops executing and the stack is unwound, running all deferred functions until the &lt;code&gt;main&lt;/code&gt; function is reached.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;panic&lt;/code&gt; and &lt;code&gt;recover&lt;/code&gt; are not intended to be used for error handling.&lt;/li&gt;
&lt;li&gt;It is better to explicitly handle errors than to use &lt;code&gt;panic&lt;/code&gt; and &lt;code&gt;recover&lt;/code&gt; because it is not clear when calling &lt;code&gt;recover&lt;/code&gt; what failed exactly.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="getting-a-stack-trace-from-an-error"&gt;Getting a Stack Trace from an Error&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Go doesn&amp;rsquo;t provide a stack trace by default outside of a &lt;code&gt;panic&lt;/code&gt; state.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;%+v&lt;/code&gt; can be used to print the stack trace with &lt;code&gt;fmt.Printf&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Pass the &lt;code&gt;-trimpath&lt;/code&gt; flag to &lt;code&gt;go build&lt;/code&gt; to remove the absolute path from the stack trace, which otherwise shows full paths to files.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="modules-packages-and-imports"&gt;Modules, Packages, and Imports&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;The module is the root of the package tree. It can be defined in &lt;code&gt;go.mod&lt;/code&gt; or inferred from the directory structure. For a GitHub repository, it is inferred from the URL as in &lt;code&gt;module github.com/{USER}/{PROJECT}&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Keep a single module per repository.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="gomod"&gt;&lt;code&gt;go.mod&lt;/code&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;go mod init MODULE_PATH&lt;/code&gt; to create a new module (&lt;code&gt;go.mod&lt;/code&gt; file).&lt;/li&gt;
&lt;li&gt;The module path is case-sensitive.&lt;/li&gt;
&lt;li&gt;The minimum version of Go required to build the module can be specified with &lt;code&gt;go mod init MODULE_PATH GO_VERSION&lt;/code&gt; and it appears in the &lt;code&gt;go.mod&lt;/code&gt; file below the module declaration.&lt;/li&gt;
&lt;li&gt;There can be a &lt;code&gt;require&lt;/code&gt; directive for each dependency.&lt;/li&gt;
&lt;li&gt;There are also two optional sections: &lt;code&gt;replace&lt;/code&gt; and &lt;code&gt;exclude&lt;/code&gt;.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;replace&lt;/code&gt; is used to replace a dependency with a local version.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;exclude&lt;/code&gt; is used to exclude a dependency from the build.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Example of a go.mod file&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;github&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;com&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;USER&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;PROJECT&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;go&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.&lt;/span&gt;&lt;span class="nx"&gt;xx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;github&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;com&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;OTHER_USER&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;OTHER_PROJECT&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;v0&lt;/span&gt;&lt;span class="mf"&gt;.0.0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20200921021027&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="nx"&gt;abc380940ae&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;github&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;com&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;shopspring&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;decimal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;v1&lt;/span&gt;&lt;span class="mf"&gt;.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="building-packages"&gt;Building packages&lt;/h2&gt;
&lt;h3 id="imports-and-exports"&gt;Imports and exports&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Import statements allow accessing exported constants, variables, functions and types from another package.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;An exported identifier starts with a capital letter&lt;/em&gt;. It cannot be accessed from another package without an import statement.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="creating-and-accessing-packages"&gt;Creating and accessing packages&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The first line of the file should be &lt;code&gt;package {PACKAGE_NAME}&lt;/code&gt;. It&amp;rsquo;s a &lt;em&gt;package clause&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Next is the import section.
&lt;ul&gt;
&lt;li&gt;Importing from the standard library doesn&amp;rsquo;t require a path.&lt;/li&gt;
&lt;li&gt;Any other imports require a path, using the module path as a prefix and appending the path to the package.&lt;/li&gt;
&lt;li&gt;Not using any identifier from a path will result in a compiler error. Hence, all code included in the build will be used.&lt;/li&gt;
&lt;li&gt;It is best to always use absolute paths for clarity.&lt;/li&gt;
&lt;li&gt;The name of a package is determined by its package clause, &lt;em&gt;not by the path&lt;/em&gt; being imported. In general, the package name should match the last element of the path.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;main&lt;/code&gt; package cannot be imported as it is the entrypoint of the application.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Package names are in the file block: the package name is the same for all files in the same directory and must be present.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="naming-packages"&gt;Naming packages&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The package name should be descriptive.&lt;/li&gt;
&lt;li&gt;Avoid &lt;code&gt;util&lt;/code&gt; and &lt;code&gt;common&lt;/code&gt; packages. Create more packages with fewer functions instead.&lt;/li&gt;
&lt;li&gt;Don&amp;rsquo;t include the name of the package in functions, as this will be disambiguated by the package name when importing.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="organizing-a-module"&gt;Organizing a module&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;There is no official structure.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;cmd&lt;/code&gt; directory is used for executables. There can be multiple executables produced by different applications from a module.&lt;/li&gt;
&lt;li&gt;When there are a bunch of files at the root to manage deployment and testing, it is a good pattern to put all packages inside a &lt;code&gt;pkg&lt;/code&gt; directory.
&lt;ul&gt;
&lt;li&gt;Inside &lt;code&gt;pkg&lt;/code&gt;, limit dependencies between packages by organizing the code according to the functionality it provides.&lt;/li&gt;
&lt;li&gt;A good primer on the topic is &lt;a href="https://www.youtube.com/watch?v=oL6JBUk6tj0"&gt;GopherCon 2018: Kat Zien - How Do You Structure Your Go Apps&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="overriding-a-packages-name"&gt;Overriding a package&amp;rsquo;s name&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;When names collide, you can use an alias to rename a package.
&lt;ul&gt;
&lt;li&gt;In the standard library, both &lt;code&gt;&amp;quot;crypto/rand&amp;quot;&lt;/code&gt; and &lt;code&gt;&amp;quot;math/rand&amp;quot;&lt;/code&gt; are imported as &lt;code&gt;&amp;quot;rand&amp;quot;&lt;/code&gt;, but they can be disambiguated with an alias such as &lt;code&gt;crand &amp;quot;crypto/rand&amp;quot;&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Using the &lt;code&gt;.&lt;/code&gt; alias is discouraged because it makes it harder to understand where a function is coming from as it will import all exported identifiers from the current namespace (same idea as &lt;code&gt;import * from ...&lt;/code&gt; in Python).&lt;/li&gt;
&lt;li&gt;Package names can be shadowed, which renders it inaccessible. Always resolve conflicts by using an alias instead.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="package-comments-and-godoc"&gt;Package comments and &lt;code&gt;godoc&lt;/code&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Comments must be placed right above the item to be documented.&lt;/li&gt;
&lt;li&gt;Comments start with &lt;code&gt;//&lt;/code&gt; and can be multiline.&lt;/li&gt;
&lt;li&gt;A blank line with &lt;code&gt;//&lt;/code&gt; is used to create paragraphs.&lt;/li&gt;
&lt;li&gt;Preformatted text can be inserted with indentation.&lt;/li&gt;
&lt;li&gt;Comments before the package clause create package-level documentation.
&lt;ul&gt;
&lt;li&gt;If the package has a lot of documentation, it is better to put it in a separate file called &lt;code&gt;doc.go&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Comments should start with the name of the item being documented.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="internal-package"&gt;Internal package&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Use the &lt;code&gt;internal&lt;/code&gt; directory to create packages that are only accessible from the parent and sibling packages.&lt;/li&gt;
&lt;li&gt;Trying to access an &lt;code&gt;internal&lt;/code&gt; package from outside the module will result in a compiler error.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="the-init-function"&gt;The &lt;code&gt;init&lt;/code&gt; function&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;If there is an &lt;code&gt;init&lt;/code&gt; function in a package, it runs as soon as the package is referenced by another package.&lt;/li&gt;
&lt;li&gt;It has not input or output parameters and can only cause side-effects within the package.&lt;/li&gt;
&lt;li&gt;There can be multiple &lt;code&gt;init&lt;/code&gt; functions in a package, even in the same file, although this setup is discouraged.&lt;/li&gt;
&lt;li&gt;A blank import can be used to run the &lt;code&gt;init&lt;/code&gt; function of a package without using any of its exported identifiers, e.g., &lt;code&gt;import _ &amp;quot;github.com/lib/pq&amp;quot;&lt;/code&gt;. Explicit is better than implicit: this is an obsolete pattern.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="circular-dependencies"&gt;Circular dependencies&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;They are &lt;strong&gt;not allowed&lt;/strong&gt; to keep the code readable and the compiler fast.&lt;/li&gt;
&lt;li&gt;If two packages depend on each other, they should probably be merged into a single package.&lt;/li&gt;
&lt;li&gt;If two packages with circular dependencies are still preferred, it may be possible to move only the culprits into a separate package so that both packages can import them.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="api-renaming-and-organizing"&gt;API renaming and organizing&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;To avoid breaking a function name, a new method can be added with the new name, calling the old one.&lt;/li&gt;
&lt;li&gt;Constants can be re-declared with the same types, but with a different name.&lt;/li&gt;
&lt;li&gt;To rename exported types, we can create an alias such as &lt;code&gt;type Bar = Foo&lt;/code&gt;. In this case, new methods should still be added to the original type to preserve backward compatibility.&lt;/li&gt;
&lt;li&gt;Caution: a field name cannot be changed without breaking backward compatibility.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="working-with-modules"&gt;Working with modules&lt;/h2&gt;
&lt;h3 id="importing-third-party-code"&gt;Importing third-party code&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;go.mod&lt;/code&gt; is used to manage dependencies.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;go.mod&lt;/code&gt; is automatically populated when a &lt;code&gt;go&lt;/code&gt; command runs and a dependency is required (e.g., &lt;code&gt;go build&lt;/code&gt;, &lt;code&gt;go list&lt;/code&gt;, &lt;code&gt;go run&lt;/code&gt;, &lt;code&gt;go test&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;go.sum&lt;/code&gt; is used to verify the integrity of the dependencies.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;god.mod&lt;/code&gt; and &lt;code&gt;go.sum&lt;/code&gt; should both be committed to version control.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="working-with-versions"&gt;Working with versions&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;go list&lt;/code&gt; is used to list dependencies used by a project.
&lt;ul&gt;
&lt;li&gt;By default, it lists packages used.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;-m&lt;/code&gt; flag is used to list modules used.&lt;/li&gt;
&lt;li&gt;Appending the &lt;code&gt;-versions&lt;/code&gt; flag to the previous command lists all versions of the dependencies.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;go get&lt;/code&gt; can be used to downgrade or upgrade a dependency (e.g., &lt;code&gt;go get github.com/{USER}/{PROJECT}@v1.0.0&lt;/code&gt;).
&lt;ul&gt;
&lt;li&gt;It can also be used to add a new dependency.&lt;/li&gt;
&lt;li&gt;It can be used to remove a dependency by adding the &lt;code&gt;-u&lt;/code&gt; flag.&lt;/li&gt;
&lt;li&gt;Changes will be reflected in &lt;code&gt;go.mod&lt;/code&gt; and &lt;code&gt;go.sum&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Dependencies might be shown with &lt;code&gt;// indirect&lt;/code&gt; next to them. This means that the dependency is not used directly by the project, but by one of its dependencies.
&lt;ul&gt;
&lt;li&gt;It can be added when the project uses that dependency directly with a newer version than what is declared in the dependency&amp;rsquo;s &lt;code&gt;go.mod&lt;/code&gt; file.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Go follows semantic versioning (&lt;em&gt;SemVer&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;There is an &lt;em&gt;import compatibility rule&lt;/em&gt;: all minor and patch versions should remain compatible and if not, this is considered a bug.
&lt;ul&gt;
&lt;li&gt;Instead of importing multiple versions of the same library as with &lt;code&gt;npm&lt;/code&gt;, Go will import the highest version of the library that satisfies the requirements.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="updating-to-compatible-versions"&gt;Updating to compatible versions&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;go get -u=patch DEPENDENCY_PATH&lt;/code&gt; to update to the latest compatible patch version.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;go get -u DEPENDENCY_PATH&lt;/code&gt; will update to the most recent compatible version.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="updating-to-incompatible-versions"&gt;Updating to incompatible versions&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Go follows the &lt;em&gt;semantic import versioning&lt;/em&gt; rule: for all major versions greater than &lt;code&gt;1&lt;/code&gt;, the major version is included in the import path, e.g., &lt;code&gt;&amp;quot;github.com/{USER}/{PROJECT}/v2&amp;quot;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Once a new major version is used in the project, &lt;code&gt;go build&lt;/code&gt; will update the &lt;code&gt;go.mod&lt;/code&gt; file to use the new major version.&lt;/li&gt;
&lt;li&gt;Older versions may still be present in &lt;code&gt;go.mod&lt;/code&gt;: &lt;code&gt;go mod tidy&lt;/code&gt; can be used to remove them.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="vendoring"&gt;Vendoring&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;go mod vendor&lt;/code&gt; is used to create a &lt;code&gt;vendor&lt;/code&gt; directory with all the dependencies to ensure reproducible builds.&lt;/li&gt;
&lt;li&gt;It dramatically increases the size of the project in version control.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="pkggodev"&gt;&lt;code&gt;pkg.go.dev&lt;/code&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;It automatically indexes Go projects.&lt;/li&gt;
&lt;li&gt;It is used to search for packages and their documentation.&lt;/li&gt;
&lt;li&gt;It publishes the godocs, license, &lt;code&gt;README&lt;/code&gt;, the module&amp;rsquo;s dependencies and which other open source projects depend on it.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="publishing-modules"&gt;Publishing modules&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Go favors permissive licenses (e.g., MIT, BSD, Apache).&lt;/li&gt;
&lt;li&gt;There is no need for a central repository, as Go uses the module path to find the module.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="versioning-modules"&gt;Versioning modules&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Minor and patch versions should be compatible and are easy to manage.&lt;/li&gt;
&lt;li&gt;Major versions are slightly more difficult to manage. For instance, let&amp;rsquo;s go from &lt;code&gt;v1&lt;/code&gt; to &lt;code&gt;v2&lt;/code&gt;.
&lt;ul&gt;
&lt;li&gt;Create a directory to put all the old code in, named &lt;code&gt;v2&lt;/code&gt;, including &lt;code&gt;README&lt;/code&gt; and &lt;code&gt;LICENSE&lt;/code&gt; files.&lt;/li&gt;
&lt;li&gt;Create a branch.
&lt;ul&gt;
&lt;li&gt;Name the branch &lt;code&gt;v1&lt;/code&gt; if the old code goes in it.&lt;/li&gt;
&lt;li&gt;Name the branch &lt;code&gt;v2&lt;/code&gt; if the new code goes in it.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Make sure the module path in &lt;code&gt;go.mod&lt;/code&gt; ends with &lt;code&gt;/v2&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Update all import paths to use the new module path.&lt;/li&gt;
&lt;li&gt;Create a tag for the new version.
&lt;ul&gt;
&lt;li&gt;Name the tag &lt;code&gt;v2.0.0&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Tag the &lt;code&gt;main&lt;/code&gt; branch if the new code goes in it.&lt;/li&gt;
&lt;li&gt;Otherwise, tag the &lt;code&gt;v2&lt;/code&gt; branch.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;If breaking changes might be introduced while on the new version, use a pre-release version, e.g., &lt;code&gt;v2.0.0-alpha.1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The open source project &lt;a href="https://github.com/marwan-at-work/mod"&gt;&lt;code&gt;mod&lt;/code&gt;&lt;/a&gt; can be used to automate this process.&lt;/li&gt;
&lt;li&gt;The Go Blog has a &lt;a href="https://go.dev/blog/v2-go-modules"&gt;post&lt;/a&gt; on the topic.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="module-proxy-servers"&gt;Module proxy servers&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Google manages a module proxy server that fetches all versions of all publicly available modules.&lt;/li&gt;
&lt;li&gt;Google also maintains a &lt;em&gt;sum database&lt;/em&gt;, which stores the checksums of all the modules.&lt;/li&gt;
&lt;li&gt;Modules are only installed from the proxy server if they are not already present in the local cache and if the checksums match.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="specifying-a-module-proxy-server"&gt;Specifying a module proxy server&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;GOPROXY&lt;/code&gt; environment variable can be used to specify a module proxy server. To use GoCenter, set it to &lt;code&gt;GOPROXY=https://gocenter.io&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If the &lt;code&gt;GOPROXY&lt;/code&gt; environment variable is set to &lt;code&gt;direct&lt;/code&gt;, the module proxy server will not be used and the module will be downloaded directly from the source.&lt;/li&gt;
&lt;li&gt;Projects such as &lt;a href="https://github.com/gomods/athens"&gt;&lt;code&gt;athens&lt;/code&gt;&lt;/a&gt; can be used to create a local module proxy server.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="concurrency-in-go"&gt;Concurrency in Go&lt;/h2&gt;
&lt;h2 id="when-to-use-concurrency"&gt;When to use concurrency&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Concurrency is not parallelism&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Concurrency is useful &lt;em&gt;when there are multiple tasks that can be executed independently&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Concurrency brings benefits &lt;em&gt;when a process takes a long time to complete&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Read &lt;a href="https://www.oreilly.com/library/view/the-art-of/9780596802424/"&gt;The Art of Concurrency&lt;/a&gt; for more information.&lt;/li&gt;
&lt;li&gt;The book &lt;a href="https://www.oreilly.com/library/view/concurrency-in-go/9781491941294/"&gt;Concurrency in Go&lt;/a&gt; is also a great resource.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="goroutines"&gt;Goroutines&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;&lt;em&gt;Goroutines are lightweight processes managed by the Go runtime&lt;/em&gt;&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;Because Go manages goroutines, they are cheap to create and destroy (no need to create system-level resources).&lt;/li&gt;
&lt;li&gt;They are memory efficient because they are allocated on the stack with small initial sizes.&lt;/li&gt;
&lt;li&gt;Switching between goroutines is fast because it is managed by the Go runtime within a process.&lt;/li&gt;
&lt;li&gt;Go optimizes how work is distributed across goroutines.
&lt;ul&gt;
&lt;li&gt;For more details on this, watch &lt;a href="https://www.youtube.com/watch?v=YHRO5WQGh0k"&gt;GopherCon 2018: Kavya Joshi - The Scheduler Saga&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;A goroutine starts by calling a function with the &lt;code&gt;go&lt;/code&gt; keyword in front of it.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="channels"&gt;Channels&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Channels are &lt;em&gt;used to communicate between goroutines&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;They are a built-in type that require the &lt;code&gt;make&lt;/code&gt; function to create them, e.g., &lt;code&gt;ch := make(chan int)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The zero value of a channel is &lt;code&gt;nil&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;They are passed as parameters to functions as a pointer.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="reading-writing-buffering"&gt;Reading, writing, buffering&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;&amp;lt;-&lt;/code&gt; operator is used to send and receive data from a channel. &lt;em&gt;It indicates the direction of the data flow&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;A function parameter can specify the direction of the channel, e.g., &lt;code&gt;func f(ch &amp;lt;-chan int)&lt;/code&gt; will make it so that the channel can only be read from. Likewise, &lt;code&gt;func f(ch chan&amp;lt;- int)&lt;/code&gt; will make it so that the channel can only be written to.&lt;/li&gt;
&lt;li&gt;By default, channels are &lt;em&gt;unbuffered&lt;/em&gt;, meaning that they can only hold one value at a time. They should be used most of the time.&lt;/li&gt;
&lt;li&gt;A channel can be buffered by specifying the buffer size when creating it. E.g., &lt;code&gt;ch := make(chan int, 10)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;len(ch)&lt;/code&gt; is used to get the number of elements in the channel.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cap(ch)&lt;/code&gt; is used to get the capacity of the channel.&lt;/li&gt;
&lt;li&gt;The capacity of a channel cannot be changed after it is created.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="for-range-and-channels"&gt;&lt;code&gt;for-range&lt;/code&gt; and channels&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;for-range&lt;/code&gt; can be used to read from a channel until it is closed, or until a &lt;code&gt;break&lt;/code&gt; or &lt;code&gt;return&lt;/code&gt; statement is encountered.&lt;/li&gt;
&lt;li&gt;There is a single variable declared for the channel, which is the value read from the channel.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;range&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="closing-a-channel"&gt;Closing a channel&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Close a channel with &lt;code&gt;close(ch)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Writing to a closed channel will result in a runtime panic.&lt;/li&gt;
&lt;li&gt;Attempting to read from a closed unbuffered channel will return the zero value of the channel&amp;rsquo;s type.&lt;/li&gt;
&lt;li&gt;Reading from a closed buffered channel will return the remaining values in the channel until it is empty, then it will return the zero value of the channel&amp;rsquo;s type.&lt;/li&gt;
&lt;li&gt;To know if a channel is closed, use the second return value of the receive operation with the &lt;em&gt;comma ok&lt;/em&gt; idiom, e.g., &lt;code&gt;v, ok := &amp;lt;-ch&lt;/code&gt;.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ok&lt;/code&gt; will be &lt;code&gt;true&lt;/code&gt; if the channel is open and &lt;code&gt;false&lt;/code&gt; if it is closed.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="how-channels-behave"&gt;How channels behave&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;They pause the execution of the goroutine until a value is available to read from the channel.&lt;/li&gt;
&lt;li&gt;They pause the execution of the goroutine until a value can be written to the channel.&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;panic&lt;/code&gt; will occur if a value is written to a closed channel or when trying to close a closed channel or a &lt;code&gt;nil&lt;/code&gt; channel.&lt;/li&gt;
&lt;li&gt;Make the writer responsible for closing the channel.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="select"&gt;&lt;code&gt;select&lt;/code&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Starvation&lt;/em&gt; is when a goroutine is waiting for a resource that is never available.&lt;/li&gt;
&lt;li&gt;It looks very similar to a &lt;code&gt;switch&lt;/code&gt; statement.&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;case&lt;/code&gt; in a &lt;code&gt;select&lt;/code&gt; statement is executed when the channel is ready to be read from or written to.&lt;/li&gt;
&lt;li&gt;If multiple &lt;code&gt;case&lt;/code&gt; statements are ready, one is chosen at random &amp;ndash; with &lt;code&gt;switch&lt;/code&gt;, the first match is always chosen. This solves the starvation problem since all cases are checked at once.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;select&lt;/code&gt; also deals with deadlock issues: if all channels are blocked, it will execute the &lt;code&gt;default&lt;/code&gt; case.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;select&lt;/code&gt; is often used in a loop to keep reading from a channel until it is closed.
&lt;ul&gt;
&lt;li&gt;Having a &lt;code&gt;default&lt;/code&gt; case inside a loop for a &lt;code&gt;select&lt;/code&gt; is most certainly not what is intended as it will run constantly.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="concurrency-practices-and-patterns"&gt;Concurrency practices and patterns&lt;/h2&gt;
&lt;h3 id="keep-apis-concurrency-free"&gt;Keep APIs concurrency-free&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Never expose channels or mutexes in an API. If a channel is exposed, the user will have to manage it, know whether it is buffered or not, closed or not or &lt;code&gt;nil&lt;/code&gt;. The user could also trigger deadlocks.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="goroutines-for-loops-and-varying-variables"&gt;Goroutines, for loops, and varying variables&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Instead of shadowing variables in a &lt;code&gt;for&lt;/code&gt; loop, pass them as parameters to the goroutine.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Don&amp;#39;t do this&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;range&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// shadowing&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Do this instead&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;range&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// value captured by the closure&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="always-clean-up-your-goroutines"&gt;Always clean up your goroutines&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;If a goroutine is not cleaned up, it will keep running until the program exits: this is called a &amp;ldquo;&lt;em&gt;goroutine leak&lt;/em&gt;&amp;rdquo;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="done-channel-pattern"&gt;&amp;ldquo;Done channel pattern&amp;rdquo;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;If multiple goroutines are running, it is useful to have a way to signal them to stop.&lt;/li&gt;
&lt;li&gt;A channel (named &lt;code&gt;done&lt;/code&gt;) can be used to signal the goroutines to stop.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="using-a-cancel-function-to-terminate-a-goroutine"&gt;Using a cancel function to terminate a goroutine&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;A cancel function can be used to terminate a goroutine.&lt;/li&gt;
&lt;li&gt;It is a function that performs a cleanup and closes a channel.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="when-to-use-buffered-and-unbuffered-channels"&gt;When to use buffered and unbuffered channels&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Buffered channels are useful when limiting the number of goroutines that can access a resource at the same time, when limiting the amount of work that gets queued up or when the number of goroutines is known.&lt;/li&gt;
&lt;li&gt;Buffered channels are good to gather results from multiple goroutines when a deterministic order is not required.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="backpressure"&gt;Backpressure&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Backpressure is a way to signal to a goroutine that it should slow down.&lt;/li&gt;
&lt;li&gt;It is implemented with buffered channels.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="turning-off-a-case-in-a-select"&gt;Turning off a case in a &lt;code&gt;select&lt;/code&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Setting a variable&amp;rsquo;s channel to &lt;code&gt;nil&lt;/code&gt; will turn off the case in a &lt;code&gt;select&lt;/code&gt; statement.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;select&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="nx"&gt;in&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// kills the case&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// ... other cases ...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="nx"&gt;done&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="time-out-code"&gt;Time out code&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;time.After&lt;/code&gt; to time out code.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;select&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// this requires context cancellation to free up resources&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// if the function is not finished before the timeout,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// else it will keep processing in the background&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="nx"&gt;ch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;After&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;timed out&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="using-waitgroups"&gt;Using &lt;code&gt;WaitGroups&lt;/code&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;em&gt;done channel pattern&lt;/em&gt; works well when waiting for a single goroutine to finish.&lt;/li&gt;
&lt;li&gt;When waiting for multiple goroutines to finish, use a &lt;code&gt;sync.WaitGroup&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Add&lt;/code&gt; is used to add a goroutine to the wait group.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Done&lt;/code&gt; is used to signal that a goroutine is done.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Wait&lt;/code&gt; is used to wait for all goroutines to finish.&lt;/li&gt;
&lt;li&gt;Use them when some cleanup is required after all goroutines are done.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pkg.go.dev/golang.org/x/sync/errgroup"&gt;&lt;code&gt;ErrGroup&lt;/code&gt;&lt;/a&gt; can be used to wait for multiple goroutines to finish and return an error if one of them fails.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;wg&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;sync&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;WaitGroup&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;wg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;chan&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;range&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// The wait group is passed with a closure&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Otherwise it would need to be passed as a pointer&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// So all goroutines share the same instance&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;defer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;wg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Done&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// called even if panic&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;wg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Wait&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;range&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="running-code-exactly-once"&gt;Running code exactly once&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;once.Do&lt;/code&gt; is used to run code exactly once.&lt;/li&gt;
&lt;li&gt;It can be found in the &lt;code&gt;sync&lt;/code&gt; package.&lt;/li&gt;
&lt;li&gt;It needn&amp;rsquo;t be initialized, as the zero value is usable.&lt;/li&gt;
&lt;li&gt;It is best to use the minimum amount of concurrency possible.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;once&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;sync&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Once&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;once&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Do&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Only once&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;once&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Do&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Only once&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// will not be printed&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="when-to-use-mutexes-instead-of-channels"&gt;When to use mutexes instead of channels&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Mutex stands for &lt;em&gt;mutual exclusion&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Mutexes limit access to a resource to a single goroutine at a time with a locking mechanism (&lt;code&gt;Lock&lt;/code&gt; and &lt;code&gt;Unlock&lt;/code&gt;, which must be used carefully to avoid creating deadlocks, especially in functions implemented recursively).&lt;/li&gt;
&lt;li&gt;They require to do more bookkeeping than channels.&lt;/li&gt;
&lt;li&gt;They should never be copied, just like &lt;code&gt;sync.WaitGroup&lt;/code&gt; and &lt;code&gt;sync.Once&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Use mutexes &lt;em&gt;when there is a shared resource that needs to be protected&lt;/em&gt;, such as a field in a struct.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RWMutex&lt;/code&gt; is used when there are multiple readers and a single writer. The &lt;em&gt;critical section&lt;/em&gt; is protected by a write lock, while the read lock is used to read the resource by multiple goroutines.&lt;/li&gt;
&lt;li&gt;Sometimes, performance issues with channels can be solved by using mutexes instead.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="atomics"&gt;Atomics&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Atomics are used to perform atomic operations on integers and pointers.&lt;/li&gt;
&lt;li&gt;They are more niche than mutexes and channels and as such, they are not covered in this introductory summary on Go.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="the-standard-library"&gt;The Standard Library&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;It is battery-included, just like Python.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="io-and-friends"&gt;&lt;code&gt;io&lt;/code&gt; and Friends&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;io&lt;/code&gt; is used to read (&lt;code&gt;io.Reader&lt;/code&gt;) and write (&lt;code&gt;io.Writer&lt;/code&gt;) data.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;io.Closer&lt;/code&gt; is used to close a resource.&lt;/li&gt;
&lt;li&gt;Read (&lt;code&gt;io.ReaderAt&lt;/code&gt;) and write (&lt;code&gt;io.WriterAt&lt;/code&gt;) data at a specific offset.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;io.Seeker&lt;/code&gt; is used to seek to a specific offset.&lt;/li&gt;
&lt;li&gt;There are other combinations to define more explicitly the code&amp;rsquo;s intent (&lt;code&gt;ReadWriter&lt;/code&gt;, &lt;code&gt;ReadCloser&lt;/code&gt;, &lt;code&gt;WriteCloser&lt;/code&gt;, &lt;code&gt;ReadWriteCloser&lt;/code&gt;, &lt;code&gt;ReadSeeker&lt;/code&gt;, &lt;code&gt;WriteSeeker&lt;/code&gt;, &lt;code&gt;ReadWriteSeeker&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;io&lt;/code&gt; package is a great example of the power of interfaces through simple abstractions.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Reader&lt;/code&gt;, &lt;code&gt;Writer&lt;/code&gt;, and &lt;code&gt;Scanner&lt;/code&gt; from the &lt;code&gt;bufio&lt;/code&gt; package are used to read and write data more efficiently on larger datasets.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="time"&gt;&lt;code&gt;time&lt;/code&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;time&lt;/code&gt; is used to work with dates and times.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;time.Time&lt;/code&gt; is used to represent a date and time. It includes the usual constants for days of the week, months, etc.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;time.Duration&lt;/code&gt; is used to represent a duration.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;time.Parse&lt;/code&gt; is used to parse a string into a &lt;code&gt;time.Time&lt;/code&gt; value.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;time.Format&lt;/code&gt; is used to format a &lt;code&gt;time.Time&lt;/code&gt; value into a string.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;time.Now&lt;/code&gt; is used to get the current time.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;time.Sleep&lt;/code&gt; is used to pause the execution of a goroutine for a specified duration.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;time.After&lt;/code&gt; is used to create a channel that will receive a value after a specified duration.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;time.Tick&lt;/code&gt; is used to create a channel that will receive a value at regular intervals.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;time.Timer&lt;/code&gt; is used to create a timer that will send a value on a channel after a specified duration.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;time.Ticker&lt;/code&gt; is used to create a ticker that will send a value on a channel at regular intervals.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;time.NewTicker&lt;/code&gt; is used to create a new ticker.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;time.NewTimer&lt;/code&gt; is used to create a new timer.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;time.Since&lt;/code&gt; is used to get the time elapsed since a specified time.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;time.Until&lt;/code&gt; is used to get the time until a specified time.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;time.AfterFunc&lt;/code&gt; is used to execute a function after a specified duration.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;Equal&lt;/code&gt; to compare two &lt;code&gt;time.Time&lt;/code&gt; values.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="monotonic-time"&gt;Monotonic time&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Go uses a monotonic clock to measure time.&lt;/li&gt;
&lt;li&gt;A monotonic clock is &lt;em&gt;a clock that counts up from the start of the computer&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="timers-and-timeouts"&gt;Timers and timeouts&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;time.NewTicker&lt;/code&gt; to create a ticker that will send a value on a channel at regular intervals.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;time.NewTimer&lt;/code&gt; instead of &lt;code&gt;time.Tick&lt;/code&gt;, as it can be stopped and reset.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="encoding-and-json"&gt;Encoding and JSON&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;&lt;em&gt;Marshalling&lt;/em&gt;&amp;rdquo; is the process of converting a data structure into a byte stream.&lt;/li&gt;
&lt;li&gt;&amp;ldquo;&lt;em&gt;Unmarshalling&lt;/em&gt;&amp;rdquo; is the process of converting a byte stream into a data structure.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="use-struct-tags-to-add-metadata"&gt;Use struct tags to add metadata&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Struct tags are strings written inside backticks that can be added to struct fields to add metadata.&lt;/li&gt;
&lt;li&gt;They can span only one line, taking the format &lt;code&gt;`tagName:&amp;quot;tagValue&amp;quot;`&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;go vet&lt;/code&gt; can be used to check for struct tags validity.&lt;/li&gt;
&lt;li&gt;If no struct tag is specified, the field name will be used instead.&lt;/li&gt;
&lt;li&gt;Use a &lt;code&gt;-&lt;/code&gt; (dash) for a field name to ignore it.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;,omitempty&lt;/code&gt; can be added right after the field name to omit a field if it is empty.&lt;/li&gt;
&lt;li&gt;While annotations can make the code more declarative and short, they can also make it harder to read and understand. &lt;strong&gt;Go&lt;/strong&gt; for readability first.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="unmarshalling-and-marshalling"&gt;Unmarshalling and marshalling&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;json.Unmarshal&lt;/code&gt; is used to unmarshal a JSON byte stream into a data structure.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;json.Marshal&lt;/code&gt; is used to marshal a data structure into a JSON byte stream.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="json-readers-and-writers"&gt;JSON, readers, and writers&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;json.Decoder&lt;/code&gt; is used to decode a JSON byte stream into a data structure.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;json.Encoder&lt;/code&gt; is used to encode a data structure into a JSON byte stream (e.g., encoding a file given an interface: &lt;code&gt;json.NewEncoder(tmpFile).Encode(toFile)&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;json.NewDecoder&lt;/code&gt; is used to create a new decoder (e.g., decoding a file given an interface: &lt;code&gt;json.NewDecoder(tmpFile2).Decode(&amp;amp;fromFile)&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;json.NewEncoder&lt;/code&gt; is used to create a new encoder.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="encoding-and-decoding-json-streams"&gt;Encoding and Decoding JSON Streams&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;json.Decoder&lt;/code&gt; and &lt;code&gt;json.Encoder&lt;/code&gt; can be used to encode and decode JSON streams.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="custom-json-parsing"&gt;Custom JSON Parsing&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;json.Unmarshaler&lt;/code&gt; is used to implement custom JSON parsing.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;json.Marshaler&lt;/code&gt; is used to implement custom JSON marshalling.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="nethttp"&gt;&lt;code&gt;net/http&lt;/code&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;As a modern language, Go has a built-in HTTP client and server.&lt;/li&gt;
&lt;li&gt;Third-party libraries of interest in this space include &lt;a href="https://github.com/go-chi/chi"&gt;chi&lt;/a&gt; and &lt;a href="https://github.com/gorilla/mux"&gt;Gorilla Mux&lt;/a&gt; for routing needs and &lt;a href="https://github.com/justinas/alice"&gt;alice&lt;/a&gt; to deal with middleware chaining.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="client"&gt;Client&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Don&amp;rsquo;t use the default client in production.&lt;/li&gt;
&lt;li&gt;Don&amp;rsquo;t use the functions to make HTTP requests directly in production as they don&amp;rsquo;t have timeouts.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="server"&gt;Server&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;http.ListenAndServe&lt;/code&gt; is used to start a server.&lt;/li&gt;
&lt;li&gt;The &lt;em&gt;middleware pattern&lt;/em&gt; is used to add functionality to a server, so as to check for authentication, logging, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="the-context"&gt;The Context&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Context is not a new feature: it is an instance that meets the &lt;code&gt;context.Context&lt;/code&gt; interface and gets passed around as the first argument to functions, which is usually named &lt;code&gt;ctx&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;context.TODO&lt;/code&gt; is used when a context is required but there is no context available. It shouldn&amp;rsquo;t be used in production.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="cancellation"&gt;Cancellation&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;context.WithCancel&lt;/code&gt; is used to create a context that can be cancelled.&lt;/li&gt;
&lt;li&gt;When a cancellable context is created, a &lt;code&gt;cancel&lt;/code&gt; function is returned. It is used to cancel the context and it &lt;strong&gt;must&lt;/strong&gt; be called (at least once) using &lt;code&gt;defer&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="timers"&gt;Timers&lt;/h2&gt;
&lt;p&gt;A server can do a few things to manage its load:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It can limit the number of concurrent requests it accepts.
&lt;ul&gt;
&lt;li&gt;It can be done by limiting the number of goroutines.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;It can limit the number of requests queued up.
&lt;ul&gt;
&lt;li&gt;This can be handled with a buffered channel.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Limit the amount of time a request can take.
&lt;ul&gt;
&lt;li&gt;The context can be used to do this.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;context.WithTimeout&lt;/code&gt; is used to create a context that will be cancelled after a specified duration.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;context.WithDeadline&lt;/code&gt; is used to create a context that will be cancelled at a specified time.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Limit the resources a request can use (memory, disk space&amp;hellip;).
&lt;ul&gt;
&lt;li&gt;There is no built-in solution for this in Go.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="values"&gt;Values&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;context.WithValue&lt;/code&gt; is used to create a context with a value.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="writing-tests"&gt;Writing Tests&lt;/h2&gt;
&lt;h2 id="basics-of-testing"&gt;Basics of testing&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;testing&lt;/code&gt; package is used to write tests.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;go test&lt;/code&gt; is used to run tests and generate reports.&lt;/li&gt;
&lt;li&gt;Tests are located in files with the suffix &lt;code&gt;_test.go&lt;/code&gt; in the same package as the code being tested, so they have access to unexported identifiers.&lt;/li&gt;
&lt;li&gt;Test functions start with &lt;code&gt;Test&lt;/code&gt; and take a &lt;code&gt;*testing.T&lt;/code&gt; parameter. They do not return any value.&lt;/li&gt;
&lt;li&gt;The test function name should be descriptive. It can start with &lt;code&gt;Test_&lt;/code&gt; to indicate the function under test is unexported.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="reporting-failure"&gt;Reporting failure&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;t.Error&lt;/code&gt; or &lt;code&gt;t.Errorf&lt;/code&gt; to report a failure and continue the test. Use it to conveniently report as many failures as possible.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;t.Fatal&lt;/code&gt; or &lt;code&gt;t.Fatalf&lt;/code&gt; to report a failure and stop the test. Use it when subsequent tests on the same function will fail or trigger a &lt;code&gt;panic&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;t.Log&lt;/code&gt; to log information about the test.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="setting-up-and-tearing-down"&gt;Setting up and tearing down&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;TestMain&lt;/code&gt; is used to set up and tear down tests.
&lt;ul&gt;
&lt;li&gt;It is called &lt;em&gt;once&lt;/em&gt; before and after all tests, not between each test.&lt;/li&gt;
&lt;li&gt;Can be used to set up and tear down a database, for instance.&lt;/li&gt;
&lt;li&gt;It can be used when package-level variables need to be initialized, although this probably means the code needs refactoring.&lt;/li&gt;
&lt;li&gt;It takes a &lt;code&gt;*testing.M&lt;/code&gt; parameter. Setup can be done at the beginning, then &lt;code&gt;exitVal := m.Run()&lt;/code&gt; is called to run tests, then teardown can be done at the end, returning the exit value with &lt;code&gt;os.Exit(exitVal)&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Individual test functions receive a &lt;code&gt;*testing.T&lt;/code&gt; parameter, which has a &lt;code&gt;Cleanup&lt;/code&gt; method that can be used to clean up after a test.
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;Cleanup&lt;/code&gt; method is similar to the &lt;code&gt;defer&lt;/code&gt; statement but can be useful is the cleanup actions are performed for multiple tests from a helper function.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="storing-sample-test-data"&gt;Storing sample test data&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;A directory named &lt;code&gt;testdata&lt;/code&gt; can be created to store sample test data for the package under test, as the package directory is used for the currently working directory.&lt;/li&gt;
&lt;li&gt;Each package accesses its own &lt;code&gt;testdata&lt;/code&gt; directory, so it is possible to have multiple &lt;code&gt;testdata&lt;/code&gt; directories in a project: up to one per package.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="caching-test-results"&gt;Caching test results&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;go test&lt;/code&gt; caches test results to speed up subsequent runs.&lt;/li&gt;
&lt;li&gt;Tests recompile if the source code or the data in &lt;code&gt;testdata&lt;/code&gt; changes.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;go test -count=1&lt;/code&gt; can be used to disable caching.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="testing-your-public-api"&gt;Testing your public API&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Create a directory &lt;code&gt;packagename_test&lt;/code&gt; to test the public API of a package, to be found at the same directory level as &lt;code&gt;packagename&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Test files in this case will be named &lt;code&gt;packagename_public_test.go&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Test your public API, not your implementation.&lt;/li&gt;
&lt;li&gt;This is used to test the exported functions and methods, not the unexported ones.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="use-go-cmp-to-compare-test-results"&gt;Use go-cmp to compare test results&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;It will output the differences between the expected and actual values in a human-readable format.&lt;/li&gt;
&lt;li&gt;It can be used to compare for strict equality as well as with custom comparators.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="table-tests"&gt;Table tests&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Table tests are used to test a function with multiple inputs and outputs.&lt;/li&gt;
&lt;li&gt;Table-driven tests are idiomatic in Go.&lt;/li&gt;
&lt;li&gt;A slice of an anonymous struct is used to store the test cases.&lt;/li&gt;
&lt;li&gt;The test function iterates over the test cases and runs the test for each of them.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Given the following:&lt;/p&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;adder&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;testing&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;TestAdd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;testing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Table of test cases&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;tests&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kd"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;expected&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Positive integers&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Negative integers&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Two zeros&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Negative and positive&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Two large integers&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;range&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;tests&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;testing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;expected&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Add(%d, %d) = %d; want %d&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The output would look like this:&lt;/p&gt;
&lt;div class="code-block code-block--wrap"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;=== RUN TestAdd
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;=== RUN TestAdd/Positive_integers
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;--- PASS: TestAdd/Positive_integers (0.00s)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;=== RUN TestAdd/Negative_integers
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;--- PASS: TestAdd/Negative_integers (0.00s)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;=== RUN TestAdd/Two_zeros
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;--- PASS: TestAdd/Two_zeros (0.00s)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;=== RUN TestAdd/Negative_and_positive
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;--- PASS: TestAdd/Negative_and_positive (0.00s)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;=== RUN TestAdd/Two_large_integers
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;--- PASS: TestAdd/Two_large_integers (0.00s)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;--- PASS: TestAdd (0.00s)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;PASS
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ok github.com/{USER}/{PROJECT}/adder 0.368s&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="checking-code-coverage"&gt;Checking code coverage&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;-cover&lt;/code&gt; flag can be used to check code coverage.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;go test -coverprofile=coverage.out&lt;/code&gt; is used to generate a coverage profile.&lt;/li&gt;
&lt;li&gt;Go ships with a very cool tool to visualize the coverage profile: &lt;code&gt;go tool cover -html=coverage.out&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="benchmarks"&gt;Benchmarks&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;The built-in testing framework can be used to write benchmarks.&lt;/li&gt;
&lt;li&gt;Benchmarks are functions that start with &lt;code&gt;Benchmark&lt;/code&gt; and take a &lt;code&gt;*testing.B&lt;/code&gt; parameter.&lt;/li&gt;
&lt;li&gt;See &lt;a href="https://jvns.ca/blog/2017/09/24/profiling-go-with-pprof/"&gt;Profiling Go programs with pprof&lt;/a&gt; for more information on profiling Go programs.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="stubs"&gt;Stubs&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;We can using function types and interfaces to create stubs.&lt;/li&gt;
&lt;li&gt;A test function can implement an interface and be passed to the function under test.&lt;/li&gt;
&lt;li&gt;A stub can be defined as a struct that implements the interface and has a field for each method of the interface. E.g., &lt;code&gt;type MathSolverStub struct {}&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;When testing larger interfaces, one can define a stub that implements only the methods required for the test.&lt;/li&gt;
&lt;li&gt;For mocks, use a mocking library such as &lt;a href="https://github.com/uber-go/mock"&gt;gomock&lt;/a&gt; or &lt;a href="https://github.com/stretchr/testify"&gt;testify&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="httptest"&gt;&lt;code&gt;httptest&lt;/code&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;httptest&lt;/code&gt; is used to test HTTP servers without having to start them.&lt;/li&gt;
&lt;li&gt;A complete, real-world example is provided in the &lt;a href="https://github.com/learning-go-book/test_examples"&gt;&lt;code&gt;test_examples&lt;/code&gt; repo&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="integration-tests-and-build-tags"&gt;Integration tests and build tags&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Integration tests are used to test the interaction between multiple components.&lt;/li&gt;
&lt;li&gt;A build tag is a comment that starts with &lt;code&gt;// +build&lt;/code&gt; and is followed by a tag name, found on the first line of a file.&lt;/li&gt;
&lt;li&gt;Files with no build tags are included in all builds.&lt;/li&gt;
&lt;li&gt;If a file has a build tag like &lt;code&gt;// +build integration&lt;/code&gt;, then it can be run with &lt;code&gt;go test -tags=integration -v ./...&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;To skip tests that take a long time to run, use &lt;code&gt;t.Skip&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;TestFileLen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;testing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;testing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Short&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Skip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;skipping test in short mode.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// ...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Skip it when testing in short mode&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// go test -short -v ./...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="finding-concurrency-problems-with-the-race-checker"&gt;Finding concurrency problems with the race checker&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;em&gt;data race&lt;/em&gt; is still possible in Go with its built-in concurrency features if a lock hasn&amp;rsquo;t been acquired.&lt;/li&gt;
&lt;li&gt;Go comes with a race checker for just these cases: &lt;code&gt;go test -race&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Adding &amp;ldquo;sleep&amp;rdquo; statements is definitely not the correct approach.&lt;/li&gt;
&lt;li&gt;The race checker can also run after building a binary: &lt;code&gt;go build -race&lt;/code&gt;. This is useful to detect race condition issues for code that is not covered by tests.&lt;/li&gt;
&lt;li&gt;Note that the race checker makes the code about 10 times slower, so use it only when needed.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="here-there-be-dragons-reflect-unsafe-and-cgo"&gt;Here There Be Dragons: Reflect, Unsafe, and Cgo&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Theses features are not used that often, but they are useful to know about.&lt;/li&gt;
&lt;li&gt;You cannot make make methods with reflection.&lt;/li&gt;
&lt;li&gt;It should only be used when there is no other way to do it.&lt;/li&gt;
&lt;li&gt;It may increase maintenance cost, because crashes can happen in production due to the lack of type safety (Java &lt;em&gt;cough&lt;/em&gt; Script &lt;em&gt;cough&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;This summary will only cover their starting point.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="reflection-to-work-with-types-at-runtime"&gt;Reflection to work with types at runtime&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;This can be used to work with data that didn&amp;rsquo;t exist at compile time.&lt;/li&gt;
&lt;li&gt;Use cases:
&lt;ul&gt;
&lt;li&gt;Reading and writing from a database;&lt;/li&gt;
&lt;li&gt;Template engines;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;fmt&lt;/code&gt; uses it heavily;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;errors&lt;/code&gt; uses it to implement &lt;code&gt;errors.Is&lt;/code&gt; and &lt;code&gt;errors.As&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sort&lt;/code&gt; uses it to sort slices of arbitrary types;&lt;/li&gt;
&lt;li&gt;Marshalling/unmarshalling JSON and XML;&lt;/li&gt;
&lt;li&gt;Comparing maps or slices for deep equality with &lt;code&gt;reflect.DeepEqual&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="types-kinds-and-values"&gt;Types, kinds, and values&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;A type is a description of a value&amp;rsquo;s structure and behavior.&lt;/li&gt;
&lt;li&gt;A kind is a description of a type&amp;rsquo;s behavior.&lt;/li&gt;
&lt;li&gt;A value is a representation of a type&amp;rsquo;s behavior.&lt;/li&gt;
&lt;li&gt;A type can have multiple kinds.&lt;/li&gt;
&lt;li&gt;A value can have multiple types.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;reflect.TypeOf&lt;/code&gt; is used to get the type of a value.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;reflect.Type&lt;/code&gt; is used to represent a type.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="making-new-values"&gt;Making new values&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;reflect.New&lt;/code&gt; is used to create a new value of a type (&lt;code&gt;reflect.Type&lt;/code&gt; as input, &lt;code&gt;reflect.Value&lt;/code&gt; as output).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="use-reflection-to-check-if-an-interfaces-value-is-nil"&gt;Use reflection to check if an interface&amp;rsquo;s value is &lt;code&gt;nil&lt;/code&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;IsValid&lt;/code&gt; is used to check if a value is valid (e.g., &lt;code&gt;iv := reflect.ValueOf(i)&lt;/code&gt;, &lt;code&gt;iv.IsValid()&lt;/code&gt;, &lt;code&gt;iv.IsNil()&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="use-reflection-to-write-a-data-marshaler"&gt;Use reflection to write a data marshaler&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;reflect.ValueOf&lt;/code&gt; is used to get the value of a field.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;reflect.Type&lt;/code&gt; is used to get the type of a field.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;reflect.StructField&lt;/code&gt; is used to get the field&amp;rsquo;s metadata.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;reflect.StructTag&lt;/code&gt; is used to get the struct tag.&lt;/li&gt;
&lt;li&gt;There is a complete example of a CSV data marshaler &lt;a href="https://go.dev/play/p/3kwe7ag1i1C"&gt;on the Go Playground&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="build-functions-with-reflection-to-automate-repetitive-tasks"&gt;Build functions with reflection to automate repetitive tasks&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;reflect.MakeFunc&lt;/code&gt; is used to create a function.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;reflect.ValueOf&lt;/code&gt; is used to get the value of a function.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;reflect.TypeOf&lt;/code&gt; is used to get the type of a function.&lt;/li&gt;
&lt;li&gt;Reflection makes the program slower.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="you-can-build-structs-with-reflection-but-dont"&gt;You can build structs with reflection, but don&amp;rsquo;t&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;reflect.StructOf&lt;/code&gt; is used to create a struct.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="unsafe-is-unsafe"&gt;&lt;code&gt;unsafe&lt;/code&gt;&amp;hellip; is unsafe&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;It allows manipulating memory directly.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Sizeof&lt;/code&gt; is used to get the size of a type (&lt;em&gt;&amp;ldquo;returns how many bytes it uses&amp;rdquo;&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Offsetof&lt;/code&gt; is used to get the offset of a field (&lt;em&gt;&amp;ldquo;returns the number of bytes from the start of the struct to the start of the field&amp;rdquo;&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Alignof&lt;/code&gt; is used to get the alignment of a field (&lt;em&gt;&amp;ldquo;returns the byte alignment it requires&amp;rdquo;&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;unsafe.Pointer&lt;/code&gt; is used to convert a pointer to a pointer of a different type. Pointer arithmetic is possible just like in C or C++.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="use-unsafe-to-convert-external-binary-data"&gt;Use unsafe to convert external binary data&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;unsafe&lt;/code&gt; is used to convert external binary data.&lt;/li&gt;
&lt;li&gt;It can be use to gain performance when interacting with the system.&lt;/li&gt;
&lt;li&gt;It can speed up marshalling and unmarshalling (about twice as fast for simple structs).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="unsafe-strings-and-slices"&gt;unsafe strings and slices&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;reflect.StringHeader&lt;/code&gt; is used to get the header of a string.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="cgo-is-for-integration-not-performance"&gt;&lt;code&gt;cgo&lt;/code&gt; is for integration, not performance&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;It is best used to integrate with C libraries.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cgo&lt;/code&gt; is the FFI (foreign function interface) of Go.&lt;/li&gt;
&lt;li&gt;You can call C functions from Go&amp;hellip; and even &lt;em&gt;Go functions from C&lt;/em&gt;!&lt;/li&gt;
&lt;li&gt;Garbage collection makes it hard to use &lt;code&gt;cgo&lt;/code&gt; for performance.&lt;/li&gt;
&lt;li&gt;Only use it when there&amp;rsquo;s no suitable Go library available.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="a-look-at-the-future-generics-in-go"&gt;A Look at the Future: Generics in Go&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Go doesn&amp;rsquo;t convert types implicitly.&lt;/li&gt;
&lt;li&gt;For a gentle introduction to the topic, there is &lt;a href="https://go.dev/doc/tutorial/generics"&gt;Tutorial: Getting started with generics&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="generics-reduce-repetitive-code-and-increase-type-safety-1"&gt;Generics reduce repetitive code and increase type safety&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Generics are akin to &amp;ldquo;type parameters&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;Without generics, Go has to use &lt;code&gt;interface{}&lt;/code&gt; and type assertions.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;any&lt;/code&gt; is used to represent any type.&lt;/li&gt;
&lt;li&gt;Generics allow specifying the type of a generic function&amp;rsquo;s parameters, such as &lt;code&gt;func Sum[T any](a, b T) T { return a + b }&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="use-type-lists-to-specify-operators"&gt;Use type lists to specify operators&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;A &amp;ldquo;type list&amp;rdquo; is a list of types.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;go&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;BuiltInOrdered&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;interface&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;float32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;float64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;uint&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;uint8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;uint16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;uint32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;uint64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;uintptr&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;hr&gt;
&lt;h2 id="salient-takeaways"&gt;Salient takeaways&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Go is a &lt;strong&gt;practical&lt;/strong&gt; language, valuing clarity of intent and readability (e.g., standard formatting is mandatory). It takes the best of other languages and leaves out the rest.&lt;/li&gt;
&lt;li&gt;Comprehensibility and explicitness is more important than conciseness in idiomatic Go.&lt;/li&gt;
&lt;li&gt;Go is &amp;ldquo;&lt;em&gt;call by value&lt;/em&gt;&amp;rdquo;, meaning it makes copies of function parameters before passing them along.&lt;/li&gt;
&lt;li&gt;Deployment is a breeze: a single binary file.&lt;/li&gt;
&lt;li&gt;Go doesn&amp;rsquo;t have classes nor inheritance, but it has structs and interfaces.&lt;/li&gt;
&lt;li&gt;Professionals use error handling profusely to make their programs more robust.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;This book achieves its goal of teaching readers how to write idiomatic Go code that leverages the strengths of the language. It focuses on real-world examples and best practices to structure Go code, rather than just explaining language syntax. The book covers a wide range of topics including primitive types, control structures, composite types like arrays and maps, concurrency, reflection, testing, and more.&lt;/p&gt;
&lt;p&gt;We covered the key takeaways from each chapter, providing a broad overview of important concepts. While not a replacement for reading the book in its entirety, this summary may serve as a helpful reference guide on the subject. Whether you are just starting with Go or are looking to improve your skills, &lt;a href="https://www.oreilly.com/library/view/learning-go/9781492077206/"&gt;Learning Go&lt;/a&gt; is an invaluable resource and I highly recommend it!&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="resources-and-references"&gt;Resources and references&lt;/h2&gt;
&lt;h2 id="articles"&gt;Articles&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://link.springer.com/article/10.1007/s10664-017-9508-2"&gt;Evaluating code complexity triggers, use of complexity measures and the influence of code complexity on maintenance time&lt;/a&gt;, Springer&lt;/li&gt;
&lt;li&gt;&lt;a href="https://go.dev/blog/v2-go-modules"&gt;Go Modules: v2 and Beyond&lt;/a&gt;, go.dev&lt;/li&gt;
&lt;li&gt;&lt;a href="https://go.dev/doc/devel/release"&gt;Go Release History&lt;/a&gt;, go.dev&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Marshalling_%28computer_science%29"&gt;Marshalling&lt;/a&gt;, Wikipedia&lt;/li&gt;
&lt;li&gt;&lt;a href="https://jvns.ca/blog/2017/09/24/profiling-go-with-pprof/"&gt;Profiling Go programs with pprof&lt;/a&gt;, Julia Evans&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="books"&gt;Books&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.oreilly.com/library/view/concurrency-in-go/9781491941294/"&gt;Concurrency in Go&lt;/a&gt;, Katherine Cox-Buday, O&amp;rsquo;Reilly&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.oreilly.com/library/view/learning-go/9781492077206/"&gt;Learning Go&lt;/a&gt;, Jon Bodner, O&amp;rsquo;Reilly&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.oreilly.com/library/view/the-art-of/9780596802424/"&gt;The Art of Concurrency&lt;/a&gt;, Clay Breshears, O&amp;rsquo;Reilly&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.oreilly.com/library/view/the-go-programming/9780134190570/"&gt;The Go Programming Language&lt;/a&gt;, Alan A. A. Donovan and Brian W. Kernighan, Addison-Wesley Professional&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="documentation"&gt;Documentation&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://cs.opensource.google/go/go/&amp;#43;/refs/tags/go1.21.2:src/strconv/atof.go"&gt;&lt;code&gt;atof.go&lt;/code&gt;&lt;/a&gt;, cs.opensource.google&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pkg.go.dev/builtin"&gt;&lt;code&gt;builtin&lt;/code&gt; documentation&lt;/a&gt;, pkg.go.dev&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/golang/go/wiki/CodeReviewComments"&gt;CodeReviewComments&lt;/a&gt;, GitHub&lt;/li&gt;
&lt;li&gt;&lt;a href="https://go.dev/doc/effective_go"&gt;Effective Go&lt;/a&gt;, go.dev&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pkg.go.dev/golang.org/x/sync/errgroup"&gt;ErrGroup&lt;/a&gt;, pkg.go.dev&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gobyexample.com/"&gt;Go By Example&lt;/a&gt;, gobyexample.com&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/golang/go/wiki"&gt;Go Wiki&lt;/a&gt;, GitHub&lt;/li&gt;
&lt;li&gt;&lt;a href="https://go.dev/doc/code"&gt;How to Write Go Code&lt;/a&gt;, go.dev&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pkg.go.dev/std"&gt;Standard library documentation&lt;/a&gt;, pkg.go.dev&lt;/li&gt;
&lt;li&gt;&lt;a href="https://go.dev/ref/spec"&gt;The Go Programming Language Specification&lt;/a&gt;, go.dev&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="other-open-source-projects-referenced"&gt;Other open source projects referenced&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/justinas/alice"&gt;Alice&lt;/a&gt;, GitHub&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/go-chi/chi"&gt;Chi&lt;/a&gt;, GitHub&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/google/go-cmp"&gt;go-cmp&lt;/a&gt;, GitHub&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gorilla/mux"&gt;Gorilla Mux&lt;/a&gt;, GitHub&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/learning-go-book"&gt;Learning Go: Code examples&lt;/a&gt;, GitHub&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/marwan-at-work/mod"&gt;Mod&lt;/a&gt;, GitHub&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="testing"&gt;Testing&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/uber-go/mock"&gt;gomock&lt;/a&gt;, GitHub&lt;/li&gt;
&lt;li&gt;&lt;a href="https://jvns.ca/blog/2017/09/24/profiling-go-with-pprof/"&gt;Profiling Go programs with pprof&lt;/a&gt;, Julia Evans&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/learning-go-book/test_examples"&gt;&lt;code&gt;test_examples&lt;/code&gt; repo&lt;/a&gt;, GitHub&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pkg.go.dev/testing"&gt;&lt;code&gt;testing&lt;/code&gt; package&lt;/a&gt;, pkg.go.dev&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/stretchr/testify"&gt;testify&lt;/a&gt;, GitHub&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="videos"&gt;Videos&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=oL6JBUk6tj0"&gt;GopherCon 2018: Kat Zien - How Do You Structure Your Go Apps&lt;/a&gt;, YouTube&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=YHRO5WQGh0k"&gt;GopherCon 2018: Kavya Joshi - The Scheduler Saga&lt;/a&gt;, YouTube&lt;/li&gt;
&lt;/ul&gt;</content:encoded><dc:creator>Sébastien Lavoie</dc:creator><pubDate>Fri, 20 Oct 2023 20:08:00 -0600</pubDate><guid isPermaLink="false">https://www.sglavoie.com/posts/book-summary-learning-go-idiomatic-approach-real-world-go-programming/</guid><category>learnings</category><category>best practices</category><category>books</category><category>go</category></item><item><title>Book summary: Refactoring UI</title><link>https://www.sglavoie.com/posts/book-summary-refactoring-ui/</link><description>Refactoring UI provides guidance for non-designers on how to create polished, professional visual interfaces without formal graphic design skills.</description><content:encoded>&lt;hr&gt;
&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;It covers core principles like establishing consistent systems for recurring elements such as spacing and typography.&lt;/li&gt;
&lt;li&gt;It advises generous use of white space and thoughtful visual hierarchy.&lt;/li&gt;
&lt;li&gt;Steps for adding depth through lighting, shadows, and layers are outlined.&lt;/li&gt;
&lt;li&gt;Recommendations are provided for working with images and illustrations effectively.&lt;/li&gt;
&lt;li&gt;Tips on elevating default elements and breaking conventions to avoid typical, cookie-cutter designs are included.&lt;/li&gt;
&lt;li&gt;Studying other designers&amp;rsquo; work and unintuitive decisions is encouraged to expand one&amp;rsquo;s skills.&lt;/li&gt;
&lt;li&gt;The goal is to equip readers with knowledge to thoughtfully craft interfaces that appear purposefully designed without simply mimicking common graphical tropes.&lt;/li&gt;
&lt;li&gt;By learning fundamental visual design concepts tailored to user interfaces, anyone can create clean, functional, and visually engaging digital experiences.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="starting-from-scratch"&gt;Starting from scratch&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Start with a feature, not a layout&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Design the shell and navigation later once you know what features you need.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Detail comes later&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Design with a big sharpie.&lt;/li&gt;
&lt;li&gt;Design in grayscale to use spacing, contrast and size to do the heavy lifting.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Don&amp;rsquo;t over-invest&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Go with low-fidelity sketches and wireframes first to move fast. Don&amp;rsquo;t get bogged down with details like fonts and colors early on.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Don&amp;rsquo;t design too much&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Work in cycles&lt;/strong&gt;: design a feature simply, build it, fix errors.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Be a pessimist&lt;/strong&gt;: expect it to be hard to build, and postpone building it (e.g., commenting system without attachments at first).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="choose-a-personality"&gt;Choose a personality&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Font choice
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Elegant/classic&lt;/em&gt;: serif&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Playful&lt;/em&gt;: Sans-serif&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Plain&lt;/em&gt;: neutral sans-serif&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Color
&lt;ul&gt;
&lt;li&gt;Blue: safe and familiar, good overall pick.&lt;/li&gt;
&lt;li&gt;Gold: expensive, sophisticated.&lt;/li&gt;
&lt;li&gt;Pink: more fun, less serious.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Border radius
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Small&lt;/em&gt; &amp;ndash; neutral, not much personality.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Large&lt;/em&gt; &amp;ndash; more playful.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;None&lt;/em&gt; &amp;ndash; more serious/formal.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Stay consistent&lt;/strong&gt; &amp;ndash; either rounded or not, same everywhere.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Language
&lt;ul&gt;
&lt;li&gt;Choose the right words for the desired tone.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Decide what you actually want
&lt;ul&gt;
&lt;li&gt;Look at the websites your expected customers use? Serious, then that&amp;rsquo;s the feel. Playful? Then that.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="limit-your-choices"&gt;Limit your choices&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Define systems in advance&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Have a working palette color and limit yourself to it.&lt;/li&gt;
&lt;li&gt;Use a type scale to avoid picking specific font sizes.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Designing by process of elimination.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Systematize&lt;/strong&gt; as much as possible to avoid repetitive low-level decisions.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="hierarchy"&gt;Hierarchy&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Visual hierarchy refers to how elements appear in importance relative to one another.&lt;/li&gt;
&lt;li&gt;Don&amp;rsquo;t let HTML semantics dictate visual styling &amp;ndash; style based on visual hierarchy.&lt;/li&gt;
&lt;li&gt;Size isn&amp;rsquo;t everything. Bold font communicates importance. &lt;em&gt;De-emphasize&lt;/em&gt; secondary/tertiary information to highlight the most important elements.&lt;/li&gt;
&lt;li&gt;Rely on &lt;em&gt;font weight&lt;/em&gt; and &lt;em&gt;color&lt;/em&gt;, not just font size, to create hierarchy.&lt;/li&gt;
&lt;li&gt;Limit yourself to &lt;em&gt;2-3 colors&lt;/em&gt; and font weights to define hierarchy.&lt;/li&gt;
&lt;li&gt;On colored backgrounds, pick a color with similar hue but lower saturation/lightness rather than just making text gray.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Avoid label&lt;/strong&gt;: value formats &amp;ndash; use formats, context, and combined labels/values for clarity without labels.&lt;/li&gt;
&lt;li&gt;Treat labels as secondary content when needed &amp;ndash; smaller, lower contrast, lighter weight.&lt;/li&gt;
&lt;li&gt;De-emphasize competing elements instead of just emphasizing the key element.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Combine labels and values&lt;/em&gt;: e.g., instead of &amp;ldquo;&lt;em&gt;In stock: 12&lt;/em&gt;&amp;rdquo;, use &amp;ldquo;&lt;em&gt;12 left in stock&lt;/em&gt;&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;Treat labels as supporting content.&lt;/li&gt;
&lt;li&gt;Design buttons based on hierarchy, not just semantics. Primary/destructive actions don&amp;rsquo;t always need prominence.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="layout-and-spacing"&gt;Layout and spacing&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Start with too much white space&lt;/strong&gt;, then remove until happy &amp;ndash; often ends up being &amp;ldquo;just enough&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;Compact layouts have their place but should be a deliberate choice, not the default.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Establish a spacing and sizing system&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;A linear scale won&amp;rsquo;t work&lt;/li&gt;
&lt;li&gt;Create a constrained spacing/sizing system based on a base unit (like &lt;code&gt;16px&lt;/code&gt;) to work faster with more consistency.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Don&amp;rsquo;t feel the need to fill the whole screen&lt;/em&gt; &amp;ndash; give elements only the space they need.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Grids are overrated&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Not all elements should be fluid&lt;/li&gt;
&lt;li&gt;Don&amp;rsquo;t shrink an element until you need to.&lt;/li&gt;
&lt;li&gt;Grids can bring order but don&amp;rsquo;t have to dictate every layout decision.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Balance layouts in columns&lt;/em&gt; instead of just making things wider.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Relative sizing doesn&amp;rsquo;t scale&lt;/em&gt;.
&lt;ul&gt;
&lt;li&gt;Fix element widths when flexibility isn&amp;rsquo;t needed.&lt;/li&gt;
&lt;li&gt;Scale elements independently &amp;ndash; don&amp;rsquo;t rely on relative units like &lt;code&gt;em&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Avoid ambiguous spacing&lt;/strong&gt;: increase spacing between groups and reduce spacing within groups to show relationships.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="text"&gt;Text&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Establish a constrained type scale&lt;/strong&gt; to speed up font size decisions and add consistency. Avoid strict modular scales.&lt;/li&gt;
&lt;li&gt;Use &lt;em&gt;pixel&lt;/em&gt; or &lt;code&gt;rem&lt;/code&gt; units &amp;ndash; not &lt;code&gt;em&lt;/code&gt; &amp;ndash; to guarantee sizes match the scale.&lt;/li&gt;
&lt;li&gt;For UI design, &lt;em&gt;pick scale values by hand&lt;/em&gt; instead of using a mathematical ratio.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use high quality fonts&lt;/strong&gt; &amp;ndash; safe bets are neutral sans-serifs and system fonts.&lt;/li&gt;
&lt;li&gt;Use the system stack if not sure: &lt;code&gt;-apple-system, Segoe UI, Roboto, Noto Sans, Ubuntu, Cantarell, Helvetica Neue;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Favor fonts with &lt;em&gt;5+ weights&lt;/em&gt; and optimized for legibility.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Keep line length between 45-75 characters&lt;/strong&gt; (20-35 &lt;code&gt;em&lt;/code&gt;) for optimal readability.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Align mixed font sizes by their baselines&lt;/strong&gt;, not centers.&lt;/li&gt;
&lt;li&gt;Use taller line-heights for small text and shorter line-heights for large text.&lt;/li&gt;
&lt;li&gt;Subtly emphasize links in UIs, no need for high contrast colors.&lt;/li&gt;
&lt;li&gt;Left align most text, right align numbers in tables. Justify only with hyphenation.&lt;/li&gt;
&lt;li&gt;Don&amp;rsquo;t center long form text.&lt;/li&gt;
&lt;li&gt;Tighten letter-spacing for headlines set in text faces. Loosen letter-spacing for all-caps.&lt;/li&gt;
&lt;li&gt;Not all links need to be emphasized boldly, especially in UIs where there is plenty of interactivity.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="colors"&gt;Colors&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;HSL&lt;/strong&gt; (&lt;em&gt;hue&lt;/em&gt;, &lt;em&gt;saturation&lt;/em&gt;, &lt;em&gt;lightness&lt;/em&gt;) is more intuitive to the human eye: use it instead of &lt;strong&gt;HEX&lt;/strong&gt; and &lt;strong&gt;RGB&lt;/strong&gt;.
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Hue&lt;/em&gt; is the color position on the color wheel. 0° is red, 120° is green, and 240° is blue.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Saturation&lt;/em&gt; represents the vividness. 0% is grey while 100% is vibrant and intense.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Lightness&lt;/em&gt; measures how close a closer is to black (0%) or white (100%), where 50% is the pure color.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HSL&lt;/strong&gt; is not the same as &lt;strong&gt;HSB&lt;/strong&gt; (&lt;code&gt;lightness != brightness&lt;/code&gt;). In &lt;strong&gt;HSB&lt;/strong&gt;, 0% brightness is always black but 100% brightness is white when saturation is set to 0%.
&lt;ul&gt;
&lt;li&gt;With 100% saturation in both HSL and HSB, 100% brightness is equivalent to 50% lightness (pure color).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Don&amp;rsquo;t rely solely on color to convey information&lt;/em&gt; - support it with other indicators.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="a-good-color-palette"&gt;A good color palette&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;You need more colors than you think - aim for &lt;em&gt;10+ shades&lt;/em&gt; of &lt;em&gt;greys&lt;/em&gt;, &lt;em&gt;primary colors&lt;/em&gt;, and &lt;em&gt;accent colors&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Grey&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;There is a lot of grey in UIs: between &lt;em&gt;8-10 shades of grey&lt;/em&gt; is a good array of options to pick from. Use very dark grey instead of true black so it looks more natural.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Primary colors&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;1 or 2 is great, with 5-10 different shades&lt;/em&gt; (e.g., Facebook is basically blue). A very light shade is good for a tinted background (e.g., alerts), darker shades work great for text.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Accent colors&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Use sparingly&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Needed to bring &lt;em&gt;semantic meaning&lt;/em&gt;, such as red for danger, yellow for warnings and green for positive trends.&lt;/li&gt;
&lt;li&gt;For a complex UI, can be as many as 10 different colors, each with 5-10 shades.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="building-a-color-palette"&gt;Building a color palette&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Define color shades upfront instead of generating on the fly. Pick base, darkest, lightest, then fill in gaps.&lt;/li&gt;
&lt;li&gt;Don&amp;rsquo;t rely purely on math to generate shades - trust your eyes and tweak if needed.&lt;/li&gt;
&lt;li&gt;Choose the base color first. This is the color in the middle that light and dark shades are derived from.&lt;/li&gt;
&lt;li&gt;Center: pick a shade that would work well as a button background.&lt;/li&gt;
&lt;li&gt;Extremes: pick the lightness color to work as a background and the darkest to work on top as text to get enough contrast.&lt;/li&gt;
&lt;li&gt;Repeat the process to pick the remaining colors in between. &lt;em&gt;9 shades is a good sweet spot as it divides cleanly&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;For grays, the base color doesn&amp;rsquo;t matter nearly as much: same process.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="perceived-brightness"&gt;Perceived brightness&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;In the HSL system, the further away a color is from 50% lightness, the more saturated it should be so it doesn&amp;rsquo;t look washed out.&lt;/li&gt;
&lt;li&gt;The perceived brightness of a color to the human eye can be calculated as follows:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;brightness = √(0.299·r² + 0.587·g² + 0.114·b²) / 255&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Green is perceived as more bright than red, which in turn is perceived as more bright than blue. With this data point, we can tweak the perceived brightness of a color by rotating the color wheel towards the desired perceived brightness.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Grays aren&amp;rsquo;t usually totally desaturated&lt;/em&gt;.
&lt;ul&gt;
&lt;li&gt;To make them feel &amp;ldquo;&lt;em&gt;cool&lt;/em&gt;&amp;rdquo; saturate them with some blue.&lt;/li&gt;
&lt;li&gt;To make them feel &amp;ldquo;&lt;em&gt;warm&lt;/em&gt;&amp;rdquo;, saturate them with yellow or orange.&lt;/li&gt;
&lt;li&gt;The same &amp;ldquo;&lt;em&gt;saturation curve&lt;/em&gt;&amp;rdquo; applies to grays: the further away from 50% brightness, the more they should be saturated to avoid looking washed out.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="a-word-on-accessibility"&gt;A word on accessibility&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Instead of having elements like dark-colored pills with a white foreground color, flip the contrast by having light-colored pills with a dark version of the color in the foreground so they won&amp;rsquo;t grab too much attention.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rotate the hue to make the color pop more&lt;/strong&gt;. For instance, instead of cranking up the lightness to meet ideal contrast ratios, rotate the hue and possibly keep the saturation high for a vibrant contrast.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Don&amp;rsquo;t rely on color alone&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Add visual cues (like arrows for upward/downward trends). Designing in grayscale first will help spot these kinds of issues.&lt;/li&gt;
&lt;li&gt;For things like a graph, playing with contrast will produce clearer results.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="depth"&gt;Depth&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Mimic how light works in the real world.
&lt;ul&gt;
&lt;li&gt;Emulate a light source coming from above to make elements appear raised or inset.&lt;/li&gt;
&lt;li&gt;For instance, with a button, if light comes from above, then the top should be lighter (e.g., &lt;code&gt;box-shadow inset&lt;/code&gt;) than the bottom (&lt;code&gt;box-shadow&lt;/code&gt;, casting shadow only below).&lt;/li&gt;
&lt;li&gt;For elements that are &amp;ldquo;inset&amp;rdquo; (I.e., more depth in the center), the opposite effect should happen: more light reaches the bottom part (vertical &lt;code&gt;box-shadow&lt;/code&gt;, going up) than the top part (&lt;code&gt;box-shadow inset&lt;/code&gt; such that it casts some shadow towards the bottom).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Don&amp;rsquo;t overdo it&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="shadows"&gt;Shadows&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Use shadows to convey elevation&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;When something appears to be raised from the background (e.g., bigger &lt;code&gt;drop-shadow&lt;/code&gt;), &lt;em&gt;it attracts the user&amp;rsquo;s focus&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Small shadows&lt;/em&gt; are useful to attract attention to the primary action to be performed.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Medium shadows&lt;/em&gt; are useful for things like a dropdown so it looks separate from the background.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Large shadows&lt;/em&gt; are great for modals.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;5 options&lt;/em&gt; is usually plenty.&lt;/li&gt;
&lt;li&gt;Can be used for interactivity, like when dragging a row from a table.&lt;/li&gt;
&lt;li&gt;A button can feel like it&amp;rsquo;s being &amp;ldquo;pressed&amp;rdquo; by reducing its shadow on click (i.e., it gets closer to the page or farther away from the user).&lt;/li&gt;
&lt;li&gt;Casting shadows
&lt;ul&gt;
&lt;li&gt;To simulate a shadow cast by &lt;em&gt;direct light&lt;/em&gt; (e.g., a long shadow behind a plant getting some sunlight), use a larger, more diffuse and subtle shadow.&lt;/li&gt;
&lt;li&gt;To simulate a shadow cast by &lt;em&gt;ambient light&lt;/em&gt; (e.g., the shadow right below the plant&amp;rsquo;s pot where light can&amp;rsquo;t hardly reach), use a narrow and darker shadow.&lt;/li&gt;
&lt;li&gt;Apply both types of shadow casting at once to create visually compelling effects.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Define a fixed set of shadows as an elevation system for consistency.&lt;/li&gt;
&lt;li&gt;Even flat designs can have depth
&lt;ul&gt;
&lt;li&gt;Flat design does not convey depth with shadows and gradients.&lt;/li&gt;
&lt;li&gt;Create depth with color: lighter colors feel closer.&lt;/li&gt;
&lt;li&gt;Can use short, offset shadows with no blur at all.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Overlap elements to create layers
&lt;ul&gt;
&lt;li&gt;E.g., position a block with a negative margin so it appears on top of two different sections.&lt;/li&gt;
&lt;li&gt;For smaller elements like avatars, an invisible border around it can make it pop better.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="images-and-contrast"&gt;Images and contrast&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Images
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Use high quality photos&lt;/em&gt; - hire a pro or use stock sites for generics. Don&amp;rsquo;t expect good results from phone pics.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Text needs consistent contrast&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Add an overlay to background images to get readable headlines.&lt;/li&gt;
&lt;li&gt;Lower the image contrast. Adjust the brightness to compensate.&lt;/li&gt;
&lt;li&gt;Colorize the image with a single color.&lt;/li&gt;
&lt;li&gt;Use text shadows instead of overlays to preserve image dynamics.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="scale"&gt;Scale&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Don&amp;rsquo;t scale up icons&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Even for SVGs, they will lack detail if they were designed correctly at a smaller scale: use a more detailed icon instead.&lt;/li&gt;
&lt;li&gt;If updating the icon is not an option, enclose it inside another shape (e.g., a circle with a background color) to occupy more space.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Don&amp;rsquo;t scale down screenshots&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Details will be distorted and hard to read.&lt;/li&gt;
&lt;li&gt;Either use a presentation from a smaller device (e.g., the tablet version on a desktop) or take a partial screenshot (e.g., &amp;ldquo;zoom in&amp;rdquo; effect with a circle or simply crop the original image).&lt;/li&gt;
&lt;li&gt;If a more complex UI needs to be presented, simplify the original image so the user doesn&amp;rsquo;t try to read a 4px font size but instead sees simpler shapes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Don&amp;rsquo;t scale down icons&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;E.g. for a favicon, redraw a simplified version instead: details will look fuzzy at a small size.&lt;/li&gt;
&lt;li&gt;User-submitted content (e.g., Instagram feed)&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Control the size and shape&lt;/em&gt;: crop images to keep the aspect ratio of containers so they don&amp;rsquo;t disturb layout (e.g., background-size: cover).&lt;/li&gt;
&lt;li&gt;Add inner shadows or borders to user images to prevent background bleed.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="finishing-touches"&gt;Finishing touches&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Use icons instead of bullets in a bulleted list.&lt;/li&gt;
&lt;li&gt;Play with size and colors. E.g., you can have huge quotes around the block of text representing a testimonial.&lt;/li&gt;
&lt;li&gt;Links deserve special styling.&lt;/li&gt;
&lt;li&gt;Use custom checkboxes and radio buttons in forms: integrate the brand&amp;rsquo;s primary color(s).&lt;/li&gt;
&lt;li&gt;Add color with accent borders, e.g. across the top of a card element, when highlighting active elements in the UI or to the left of alert messages.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Decorate backgrounds&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;Change the background color. Works great for different page sections.&lt;/li&gt;
&lt;li&gt;Can use gradients: use two hues that are within 30˚ of each other.&lt;/li&gt;
&lt;li&gt;Use repeating patterns.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Consider the empty state carefully&lt;/strong&gt;, especially when the user is meant to fill the UI with data.
&lt;ul&gt;
&lt;li&gt;Prioritize empty states with illustrations and clear calls to action.&lt;/li&gt;
&lt;li&gt;I.e., a contact page with no contacts should feel welcoming, with some icon and button to add a contact instead of a blank page with an error-like statement.&lt;/li&gt;
&lt;li&gt;Similarly, things like dashboard may present a bunch of options that won&amp;rsquo;t apply until there is something to show: simplify the user experience.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use less borders&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Use box shadows, spacing, and color instead of borders to distinguish elements.&lt;/li&gt;
&lt;li&gt;Have two background colors for containers (e.g., darker footer that looks separate from the main content).&lt;/li&gt;
&lt;li&gt;Replace borders with additional spacing.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Make components more exciting&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;E.g., a table may not need all its columns if a particular column does not need to be sorted and could instead be part of another one (e.g., combining a dollar amount with a plan type or a person&amp;rsquo;s name with its title).&lt;/li&gt;
&lt;li&gt;Radio buttons could be cards instead if they are an important part of the UI.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="next-level"&gt;Next level&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Look for unintuitive decisions in designs you admire to find new ideas.&lt;/li&gt;
&lt;li&gt;Rebuild interfaces you love to discover small details that make them exceptional.&lt;/li&gt;
&lt;li&gt;Study others to build a solid foundation.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The concepts covered in this book demonstrate that effective visual design does not require innate artistic talent or formal training. By approaching interfaces methodically, establishing constraints through systems for recurring elements, and learning to strategically apply principles like visual hierarchy, white space, and depth cues, anyone can create designs that appear polished and purposeful. While internalizing these fundamentals does take practice, the ideas presented remove much of the subjective, nuanced expertise needed for things like picking complementary colors or balancing composition in illustrations.&lt;/p&gt;
&lt;p&gt;By focusing on interfaces rather than free-form graphical work, the required skills become more structured and intentional choices drive outcomes. While studying formally can provide more breadth, the core principles in this text are enough to equip non-designers with the ability to build clean, intuitive, and aesthetically pleasing digital products. By implementing the recommendations covered, engineers and others new to design can gain confidence in their interface design skills. A great, concise read!&lt;/p&gt;</content:encoded><dc:creator>Sébastien Lavoie</dc:creator><pubDate>Sat, 09 Sep 2023 17:56:00 -0600</pubDate><guid isPermaLink="false">https://www.sglavoie.com/posts/book-summary-refactoring-ui/</guid><category>learnings</category><category>best practices</category><category>books</category><category>design</category><category>refactoring</category><category>skimming-notes</category><category>ui</category></item><item><title>Book summary: Effective Java</title><link>https://www.sglavoie.com/posts/book-summary-effective-java/</link><description>The following are some notes I have taken while reading Effective Java (Third Edition), written by Joshua Bloch. Each item is an actual heading taken verbatim from the book, while the bullet points are my rehash of the original content.</description><content:encoded>&lt;hr&gt;
&lt;h2 id="book-summary"&gt;Book summary&lt;/h2&gt;
&lt;h2 id="creating-and-destroying-objects"&gt;Creating and destroying objects&lt;/h2&gt;
&lt;h3 id="item-1-consider-static-factory-methods-instead-of-constructors"&gt;Item 1: Consider static factory methods instead of constructors&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Use static factory methods to increase readability and make classes more flexible (e.g., &lt;code&gt;Foo.withOpenBar()&lt;/code&gt; instead of &lt;code&gt;new Foo(true)&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-2-consider-a-builder-when-faced-with-many-constructor-parameters"&gt;Item 2: Consider a builder when faced with many constructor parameters&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;When a class has many parameters, use a builder instead of a &amp;ldquo;&lt;em&gt;telescoping constructor pattern&lt;/em&gt;&amp;rdquo; (i.e., having a separate method to call the class with any number of parameters, which may or may not all be used, leading to confusion and difficulty to use).&lt;/li&gt;
&lt;li&gt;The &amp;ldquo;JavaBeans pattern&amp;rdquo; uses setters and a parameter-less constructor, allowing the use of any parameters as needed when using the code (e.g., &lt;code&gt;Foo.setMethod()&lt;/code&gt;). This allows the class to enter in an inconsistent state (it is difficult to guarantee that a combination of used parameters makes sense) and makes it difficult to create an immutable class.&lt;/li&gt;
&lt;li&gt;This pattern allows calling code like &lt;code&gt;NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8).calories(100).sodium(35).carbohydrate(27).build();&lt;/code&gt;, which basically instantiate a class with optional parameters as would be the case in Python.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-3-enforce-the-singleton-property-with-a-private-constructor-or-an-enum-type"&gt;Item 3: Enforce the singleton property with a private constructor or an enum type&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The recommended path forward is to use an &lt;code&gt;enum&lt;/code&gt; type like so:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;java&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;enum&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;MyClass&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;INSTANCE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;myMethod&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;MyClass&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;MyClass&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;INSTANCE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;myMethod&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="item-4-enforce-non-instantiability-with-a-private-constructor"&gt;Item 4: Enforce non-instantiability with a private constructor&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Simply define the class constructor to be &lt;code&gt;private&lt;/code&gt; so that the class cannot be instantiated. This is useful for utility classes that may contain a bunch of static methods where instantiating the class itself is nonsensical.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-5-prefer-dependency-injection-to-hardwiring-resources"&gt;Item 5: Prefer dependency injection to hardwiring resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The example given with a &lt;code&gt;SpellChecker&lt;/code&gt; that depends on a &lt;code&gt;Dictionary&lt;/code&gt; makes a lot of sense: instead of having a class &lt;code&gt;SpellChecker&lt;/code&gt; define a &lt;code&gt;Dictionary&lt;/code&gt; that won’t be reusable elsewhere or that may need to change, pass the &lt;code&gt;Dictionary&lt;/code&gt; into the constructor of the class so that different dictionaries can be used with the same class, making it easier to test things independently and update an existing implementation.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-6-avoid-creating-unnecessary-objects"&gt;Item 6: Avoid creating unnecessary objects&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The author provides two striking examples of where creating unnecessary objects can be detrimental to performance: using &lt;code&gt;Long sum = 0L;&lt;/code&gt; instead of &lt;code&gt;long sum = 0L;&lt;/code&gt; when summing up positive integers and matching a regular expression on a string repeatedly instead of compiling the regular expression once for re-use. In short, avoid creating unnecessary objects and prefer primitives over boxed primitives.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-7-eliminate-obsolete-object-references"&gt;Item 7: Eliminate obsolete object references&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The author provides an example of a stack implementation that has a memory leak because the stack maintains obsolete references to objects that have been popped off the stack. The solution is to null out references once they are no longer needed, which in this case happened in a class where manual memory management was occurring. This is a problem because the garbage collector has no way of knowing that the objects it references after a certain portion of the array are no longer needed.&lt;/li&gt;
&lt;li&gt;The author also shows an example of a cache that uses a &lt;code&gt;WeakHashMap&lt;/code&gt; to store the cache, which allows the garbage collector to remove entries from the cache when they are no longer referenced elsewhere in the program.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-8-avoid-finalizers-and-cleaners"&gt;Item 8: Avoid finalizers and cleaners&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;&lt;em&gt;Finalizers are unpredictable, often dangerous, and generally unnecessary.&lt;/em&gt;&amp;rdquo; They can lead to performance issues and resource leaks. They should be avoided. There is no guarantee that they will be called in a timely manner, or at all.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-9-prefer-try-with-resources-to-try-finally"&gt;Item 9: Prefer try-with-resources to try-finally&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The author provides an example of a class that reads the first line of a file and returns it as a string. The class uses a &lt;code&gt;BufferedReader&lt;/code&gt; to read the file and a &lt;code&gt;FileReader&lt;/code&gt; to open the file. The problem is that the &lt;code&gt;FileReader&lt;/code&gt; is never closed, which can lead to resource leaks. The solution is to use a &lt;code&gt;try-with-resources&lt;/code&gt; block, which will automatically close the &lt;code&gt;FileReader&lt;/code&gt; when the block is exited.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="methods-common-to-all-objects"&gt;Methods common to all objects&lt;/h2&gt;
&lt;h3 id="item-10-obey-the-general-contract-when-overriding-equals"&gt;Item 10: Obey the general contract when overriding &lt;code&gt;equals&lt;/code&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;equals&lt;/code&gt; method must be reflexive, symmetric, transitive, consistent, and &lt;code&gt;x.equals(null)&lt;/code&gt; must return &lt;code&gt;false&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;It is generally a bad idea to &lt;code&gt;@Override&lt;/code&gt; the &lt;code&gt;equals&lt;/code&gt; method when inheriting from a concrete class, as it is difficult to ensure that the contract is respected. It is better to use composition instead of inheritance in this case.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-11-always-override-hashcode-when-you-override-equals"&gt;Item 11: Always override &lt;code&gt;hashCode&lt;/code&gt; when you override &lt;code&gt;equals&lt;/code&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;If two objects are equal according to the &lt;code&gt;equals&lt;/code&gt; method, they must have the same hash code. The reverse is not true: two objects with the same hash code are not necessarily equal.&lt;/li&gt;
&lt;li&gt;Using the AutoValue framework in Java, it is possible to automatically generate &lt;code&gt;equals&lt;/code&gt; and &lt;code&gt;hashCode&lt;/code&gt; methods for a class.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-12-always-override-tostring"&gt;Item 12: Always override &lt;code&gt;toString&lt;/code&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;toString&lt;/code&gt; method should return a concise, useful description of the object. It should be overridden in every class unless the class is a utility class or a small value class.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;toString&lt;/code&gt; method should return all of the interesting information contained in the object when it is practical to do so. It should not return the memory address of the object.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-13-override-clone-judiciously"&gt;Item 13: Override &lt;code&gt;clone&lt;/code&gt; judiciously&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;clone&lt;/code&gt; method is broken in Java. It is better to use a copy constructor or a copy factory instead of the &lt;code&gt;clone&lt;/code&gt; method.&lt;/li&gt;
&lt;li&gt;One exception is when a class implements the &lt;code&gt;Cloneable&lt;/code&gt; interface and has a final field that is a reference to an array or a final field that is a reference to an object. In this case, the &lt;code&gt;clone&lt;/code&gt; method can be used to create a copy of the object.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-14-consider-implementing-comparable"&gt;Item 14: Consider implementing &lt;code&gt;Comparable&lt;/code&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Implement the &lt;code&gt;Comparable&lt;/code&gt; interface when a class has a natural ordering. This allows the class to be used in sorted collections and provides a way to compare objects of the class.&lt;/li&gt;
&lt;li&gt;An example is given to compare phone numbers using the &lt;code&gt;Comparable&lt;/code&gt; interface, where chaining happens in order to compare from the most significant field to the least significant field, e.g.:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;java&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Comparable with comparator construction methods&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Comparator&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PhoneNumber&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;COMPARATOR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;comparingInt&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;PhoneNumber&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;areaCode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;thenComparingInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;prefix&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;thenComparingInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;lineNum&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;compareTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PhoneNumber&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;COMPARATOR&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;compare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="classes-and-interfaces"&gt;Classes and interfaces&lt;/h2&gt;
&lt;h3 id="item-15-minimize-the-accessibility-of-classes-and-members"&gt;Item 15: Minimize the accessibility of classes and members&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Make each class or member as inaccessible as possible. This allows for better encapsulation and makes it easier to change the implementation of a class without breaking the code that uses it.&lt;/li&gt;
&lt;li&gt;In public classes, instance fields should rarely be public, as that generally makes the classes themselves non-thread-safe. Instead, use accessor methods to access the fields.&lt;/li&gt;
&lt;li&gt;Static final fields can be made public if they are immutable.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-16-in-public-classes-use-accessor-methods-not-public-fields"&gt;Item 16: In public classes, use accessor methods, not public fields&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;When a class needs to be accessed outside of its package, provide accessor methods instead of making the fields public. This allows the class to change its implementation without breaking the code that uses it.&lt;/li&gt;
&lt;li&gt;This does not really apply to nested or private classes that are only used within the package as long as they still represent data structures usefully, as this leads to less visual clutter.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-17-minimize-mutability"&gt;Item 17: Minimize mutability&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Don&amp;rsquo;t allow the class to use &lt;em&gt;mutators&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Prevent the class from being extendable.&lt;/li&gt;
&lt;li&gt;Make all fields final.&lt;/li&gt;
&lt;li&gt;Make all fields private.&lt;/li&gt;
&lt;li&gt;Don&amp;rsquo;t write setters when they are not needed.&lt;/li&gt;
&lt;li&gt;Reducing the number of states a class can find itself in makes it easier to reason about the class and reduces the number of bugs that can occur.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-18-favor-composition-over-inheritance"&gt;Item 18: Favor composition over inheritance&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Inheritance is often overused and can lead to fragile code. It is better to use composition instead of inheritance where appropriate.&lt;/li&gt;
&lt;li&gt;When a class takes a reference to another class as a parameter in its constructor while extending the interface for the class it is taking as a parameter via a forwarding class, it is using composition, as it calls &lt;code&gt;super(otherClass)&lt;/code&gt; in its constructor. This allows the class passed as a parameter to be extended without having to change the class itself. In this way, the class using composition becomes a wrapper that can add functionality on top of the class it is wrapping. The books gives an example of a &lt;code&gt;ForwardingSet&lt;/code&gt; that extends &lt;code&gt;Set&lt;/code&gt; and takes a &lt;code&gt;Set&lt;/code&gt; as a parameter in its constructor. The &lt;code&gt;ForwardingSet&lt;/code&gt; can then add functionality on top of the &lt;code&gt;Set&lt;/code&gt; it is wrapping, in this case by counting the number of times the &lt;code&gt;add&lt;/code&gt; method is called.&lt;/li&gt;
&lt;li&gt;The main, appropriate use case for inheritance is when a class is a subtype of another class and satisfies the &lt;em&gt;is-a&lt;/em&gt; relationship.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-19-design-and-document-for-inheritance-or-else-prohibit-it"&gt;Item 19: Design and document for inheritance or else prohibit it&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;To test a class for inheritance, try to extend it. If it is not possible to extend the class, it is not designed for inheritance.&lt;/li&gt;
&lt;li&gt;No &lt;em&gt;overridable&lt;/em&gt; methods should be called in the constructor, because the superclass runs before the subclass, and the subclass will not have been initialized yet.&lt;/li&gt;
&lt;li&gt;It is better to prohibit inheritance by declaring a class to be &lt;code&gt;final&lt;/code&gt; and ensuring that no constructors are accessible.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-20-prefer-interfaces-to-abstract-classes"&gt;Item 20: Prefer interfaces to abstract classes&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Interfaces are better than abstract classes because they allow for multiple inheritance, they allow for the creation of mixins, and they allow for the creation of &lt;em&gt;tag interfaces&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Interfaces can define types that do not need to be represented hierarchically. For instance, a &lt;code&gt;DirectorPhotographer&lt;/code&gt; interface can be created that extends both the &lt;code&gt;Director&lt;/code&gt; and &lt;code&gt;Photographer&lt;/code&gt; interfaces.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-21-design-interfaces-for-posterity"&gt;Item 21: Design interfaces for posterity&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Multiple programmers should implement interfaces in different ways, and multiple client programs should use the interfaces to ensure they satisfy all intended uses. Flaws in interfaces are easier to correct before release.&lt;/li&gt;
&lt;li&gt;The moral is to be cautious when adding methods to existing interfaces using default methods and to thoroughly test and design interfaces to avoid issues and flaws in the long term.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-22-use-interfaces-only-to-define-types"&gt;Item 22: Use interfaces only to define types&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Interfaces serve as types that define what a client can do with instances of a class that implements the interface.&lt;/li&gt;
&lt;li&gt;Constant interfaces consist solely of static final fields, exporting constants. They are a poor use of interfaces as they expose implementation details and confuse users.
&lt;ul&gt;
&lt;li&gt;Implementing a constant interface leaks implementation details into the class&amp;rsquo;s API and creates a commitment to maintain binary compatibility. Subclasses of a class implementing a constant interface are also affected.&lt;/li&gt;
&lt;li&gt;If constants are tied to an existing class or interface, add them directly to that class or interface. If constants are best viewed as members of an enumerated type, use an enum type. Otherwise, use a noninstantiable utility class to export the constants.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Interfaces should be designed to define types and not used solely for the purpose of exporting constants.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-23-prefer-class-hierarchies-to-tagged-classes"&gt;Item 23: Prefer class hierarchies to tagged classes&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Tagged classes are verbose, error-prone, and inefficient. They have boilerplate code, mix multiple implementations in a single class, increase memory footprint, require careful initialization, and make it difficult to add new flavors.
&lt;ul&gt;
&lt;li&gt;Instead, abstract classes can be used as the root of the hierarchy, with concrete subclasses representing each flavor.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Class hierarchies eliminate the shortcomings of tagged classes. They are simpler, clearer, have no boilerplate, ensure field initialization, prevent missing cases, support independent extensibility, and provide distinct data types for each flavor.
&lt;ul&gt;
&lt;li&gt;Class hierarchies can reflect natural relationships among types. For example, a square can be represented as a subclass of a rectangle in the hierarchy.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-24-favor-static-member-classes-over-nonstatic"&gt;Item 24: Favor static member classes over nonstatic&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;There are four kinds of nested classes in Java: static member classes, nonstatic member classes (inner classes), anonymous classes, and local classes.
&lt;ul&gt;
&lt;li&gt;Static member classes are ordinary classes declared inside another class and have access to all members of the enclosing class. They are static members of their enclosing class and serve as public helper classes. They obey the same accessibility rules as other static members.&lt;/li&gt;
&lt;li&gt;Nonstatic member classes are implicitly associated with an instance of the enclosing class and can access methods and fields of the enclosing instance. They require an enclosing instance to be created and cannot exist independently.&lt;/li&gt;
&lt;li&gt;Private static member classes are used to represent components of the object represented by their enclosing class. They don&amp;rsquo;t require access to the enclosing instance and avoid unnecessary memory usage compared to nonstatic member classes.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;If a member class doesn&amp;rsquo;t require access to an enclosing instance, it should be declared as a static member class to avoid the overhead of an extra reference and potential memory leaks.&lt;/li&gt;
&lt;li&gt;Static member classes are preferred over nonstatic member classes unless access to the enclosing instance is necessary.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-25-limit-source-files-to-a-single-top-level-class"&gt;Item 25: Limit source files to a single top-level class&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The risks stem from the possibility of providing multiple definitions for a class, and the order in which source files are passed to the compiler determines which definition is used.&lt;/li&gt;
&lt;li&gt;If there is a need to group related classes, consider using static member classes as an alternative. Static member classes enhance readability and allow for reduced accessibility by declaring them private.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="generics"&gt;Generics&lt;/h2&gt;
&lt;h3 id="item-26-dont-use-raw-types"&gt;Item 26: Don&amp;rsquo;t use raw types&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Raw types are generic types used without specifying any type parameters.&lt;/li&gt;
&lt;li&gt;Using raw types can lead to errors at runtime (the compiler doesn&amp;rsquo;t provide type safety) and should be avoided.&lt;/li&gt;
&lt;li&gt;Instead of using raw types, it is recommended to use parameterized types to ensure type safety and expressiveness.&lt;/li&gt;
&lt;li&gt;Unbounded wildcard types (e.g., &lt;code&gt;Set&amp;lt;?&amp;gt;&lt;/code&gt;) can be used when the actual type parameter is unknown or doesn&amp;rsquo;t matter: they offer flexibility while still maintaining type safety.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-27-eliminate-unchecked-warnings"&gt;Item 27: Eliminate unchecked warnings&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Some unchecked warnings are easy to eliminate by specifying the type parameter or using the diamond operator (&lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Treat unchecked warnings seriously and make efforts to eliminate them, ensuring type safety and reducing the potential for ClassCastException at runtime.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-28-prefer-lists-to-arrays"&gt;Item 28: Prefer lists to arrays&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Arrays are covariant, which means if &lt;code&gt;Sub&lt;/code&gt; is a subtype of &lt;code&gt;Super&lt;/code&gt;, then the array type &lt;code&gt;Sub[]&lt;/code&gt; is a subtype of the array type &lt;code&gt;Super[]&lt;/code&gt;. Generics, on the other hand, are invariant.&lt;/li&gt;
&lt;li&gt;Arrays are reified, meaning they enforce their element type at runtime, while generics use erasure, enforcing their type constraints only at compile time.&lt;/li&gt;
&lt;li&gt;Arrays do not provide compile-time type safety, and errors may only be discovered at runtime, which is undesirable.&lt;/li&gt;
&lt;li&gt;Generic collections should be used instead of arrays to ensure better type safety and interoperability.&lt;/li&gt;
&lt;li&gt;Using lists instead of arrays allows for better compile-time type safety, even if it sacrifices some conciseness or performance.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-29-favor-generic-types"&gt;Item 29: Favor generic types&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The use of generic types eliminates the need for explicit casts and ensures type safety at compile time.&lt;/li&gt;
&lt;li&gt;Bounded type parameters can be used to restrict the permissible values of type parameters in generic types, allowing for more specific behavior without explicit casting.&lt;/li&gt;
&lt;li&gt;It is recommended to use generic types whenever possible to avoid casting and improve type safety. Existing non-generic types should be &lt;em&gt;generified&lt;/em&gt;, making them easier to use without breaking existing clients.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-30-favor-generic-methods"&gt;Item 30: Favor generic methods&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;To write a generic method, add type parameters to its declaration and use those type parameters throughout the method.&lt;/li&gt;
&lt;li&gt;Generic methods provide type safety and ease of use by eliminating the need for explicit casts.&lt;/li&gt;
&lt;li&gt;Bounded wildcard types can be used in generic methods to make them more flexible and allow for different types of arguments.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-31-use-bounded-wildcards-to-increase-api-flexibility"&gt;Item 31: Use bounded wildcards to increase API flexibility&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Parameterized types are invariant, meaning that &lt;code&gt;List&amp;lt;String&amp;gt;&lt;/code&gt; is not a subtype of &lt;code&gt;List&amp;lt;Object&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Wildcard types allow you to specify that a parameter can be a subtype of a certain type, using &lt;code&gt;? extends Type&lt;/code&gt; for producers and &lt;code&gt;? super Type&lt;/code&gt; for consumers.&lt;/li&gt;
&lt;li&gt;Wildcard types should not be used as return types.&lt;/li&gt;
&lt;li&gt;Wildcard types are particularly useful when working with comparables and comparators.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-32-combine-generics-and-varargs-judiciously"&gt;Item 32: Combine generics and &lt;code&gt;varargs&lt;/code&gt; judiciously&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Varargs&lt;/code&gt; methods and generics do not interact well due to the nature of &lt;code&gt;varargs&lt;/code&gt; creating arrays to hold the arguments.&lt;/li&gt;
&lt;li&gt;Alternatively, using a List parameter instead of a generic &lt;code&gt;varargs&lt;/code&gt; parameter can provide type safety, relying on the &lt;code&gt;List.of&lt;/code&gt; method to handle a variable number of arguments. The code may be slightly more verbose and slower.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-33-consider-typesafe-heterogeneous-containers"&gt;Item 33: Consider typesafe heterogeneous containers&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Common uses of generics involve parameterizing the container itself, such as &lt;code&gt;Set&amp;lt;E&amp;gt;&lt;/code&gt; and &lt;code&gt;Map&amp;lt;K,V&amp;gt;&lt;/code&gt;, which limits the number of type parameters per container.&lt;/li&gt;
&lt;li&gt;Runtime type safety can be achieved by checking the type relationship between the key and the instance being stored using a dynamic cast.&lt;/li&gt;
&lt;li&gt;Bounded type tokens can be used to restrict the types that can be passed as keys by using a bounded type parameter or a bounded wildcard.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="enums-and-annotations"&gt;Enums and annotations&lt;/h2&gt;
&lt;h3 id="item-34-use-enums-instead-of-int-constants"&gt;Item 34: Use enums instead of &lt;code&gt;int&lt;/code&gt; constants&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Some variants use String constants instead of int constants, but this approach has even more disadvantages. It can lead to errors, performance issues, and lacks type safety.&lt;/li&gt;
&lt;li&gt;Enum types in Java are full-fledged classes and offer type safety, expressive power, and additional benefits.&lt;/li&gt;
&lt;li&gt;Enum types consist of a fixed set of constants, each represented as an instance of the enum class. Enum constants are exported via public static final fields. Enum types are effectively final and can&amp;rsquo;t be extended or instantiated outside the declared constants.&lt;/li&gt;
&lt;li&gt;Enum types provide compile-time type safety. If you declare a parameter or variable of an enum type, the compiler ensures that only valid enum constants can be assigned or passed as arguments.&lt;/li&gt;
&lt;li&gt;Each enum type has its own namespace, allowing identically named constants in different enum types without conflicts.&lt;/li&gt;
&lt;li&gt;Enum types can have methods, fields, and can implement interfaces.&lt;/li&gt;
&lt;li&gt;Enum types have comparable performance to int constants. The space and time cost of loading and initializing enum types is usually negligible.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-35-use-instance-fields-instead-of-ordinals"&gt;Item 35: Use instance fields instead of ordinals&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;While it&amp;rsquo;s possible to derive associated int values from the ordinal, it is strongly discouraged. Using ordinal-based calculations for associated values can lead to maintenance issues and limitations.&lt;/li&gt;
&lt;li&gt;The recommended solution is to store associated int values in instance fields instead of deriving them from the ordinal. By assigning each enum constant a specific value in the constructor, you can avoid the pitfalls of relying on the ordinal.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-36-use-enumset-instead-of-bit-fields"&gt;Item 36: Use &lt;code&gt;EnumSet&lt;/code&gt; instead of bit fields&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Traditionally, if the elements of an enumerated type are used primarily in sets, the int enum pattern (Item 34) is used. Each constant is assigned a different power of 2, allowing bitwise OR operations to combine multiple constants into a set.
&lt;ul&gt;
&lt;li&gt;It is harder to interpret a bit field when printed as a number compared to a simple int enum constant.&lt;/li&gt;
&lt;li&gt;There is no easy way to iterate over all the elements represented by a bit field.&lt;/li&gt;
&lt;li&gt;Bit fields require choosing a specific type (int or long) with a fixed width, which limits the maximum number of bits that can be used without changing the API.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;EnumSet&lt;/code&gt; provides type safety and interoperability, just like any other set implementation.
&lt;ul&gt;
&lt;li&gt;Built-in operations: Bulk operations like removeAll and retainAll are implemented efficiently using bitwise arithmetic.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-37-use-enummap-instead-of-ordinal-indexing"&gt;Item 37: Use &lt;code&gt;EnumMap&lt;/code&gt; instead of ordinal indexing&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Ordinal indexing involves using an enum&amp;rsquo;s ordinal value as an index to access elements in an array or list. Problems:
&lt;ul&gt;
&lt;li&gt;Using ordinals directly lacks the type safety provided by enums.&lt;/li&gt;
&lt;li&gt;Due to the incompatibility of arrays with generics, the program requires an unchecked cast, resulting in a compile-time warning.&lt;/li&gt;
&lt;li&gt;If the ordinal values change, the code breaks, and there&amp;rsquo;s no compile-time checking to ensure correct indexing.&lt;/li&gt;
&lt;li&gt;When using a two-dimensional array indexed by ordinals, the size of the table grows quadratically, even if some entries are null.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;EnumMap&lt;/code&gt; is a specialized map implementation designed to work efficiently with enum keys.
&lt;ul&gt;
&lt;li&gt;They provide type safety, eliminating the need for unchecked casts. They also allow for cleaner code with no manual labeling of output.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-38-emulate-extensible-enums-with-interfaces"&gt;Item 38: Emulate extensible enums with interfaces&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Enum types in Java are not extensible by design.&lt;/li&gt;
&lt;li&gt;The basic idea is to define an interface for the opcode type and an enum that implements this interface.&lt;/li&gt;
&lt;li&gt;Emulating extensible enums with interfaces provides flexibility but has limitations. Implementations cannot be inherited from one enum type to another, and some code duplication may occur. Shared functionality can be encapsulated in a helper class or static helper method to reduce duplication.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-39-prefer-annotations-to-naming-patterns"&gt;Item 39: Prefer annotations to naming patterns&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Annotations offer a superior alternative to naming patterns. They address the shortcomings of naming patterns by providing compile-time checking, better enforcement of usage constraints, and support for associating parameter values with program elements (e.g., &lt;code&gt;@Test&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;While most programmers may not need to define their own annotation types, they should use predefined annotations provided by Java and consider using annotations provided by IDEs or static analysis tools. These annotations can enhance code quality and diagnostic information.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-40-consistently-use-the-override-annotation"&gt;Item 40: Consistently use the &lt;code&gt;Override&lt;/code&gt; annotation&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;@Override&lt;/code&gt; annotation is used on method declarations to indicate that the annotated method overrides a declaration in a supertype (class or interface).&lt;/li&gt;
&lt;li&gt;Consistently using &lt;code&gt;@Override&lt;/code&gt; protects against bugs by ensuring that overridden methods are correctly implemented. It helps catch errors where a method is intended to override a superclass method but ends up overloading it instead.&lt;/li&gt;
&lt;li&gt;In abstract classes and interfaces, it is worth annotating all methods that are believed to override superclass or super-interface methods, regardless of their nature (concrete or abstract). This helps ensure correctness and prevents accidental additions of new methods.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-41-use-marker-interfaces-to-define-types"&gt;Item 41: Use marker interfaces to define types&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;A marker interface is an interface that contains &lt;em&gt;no method declarations&lt;/em&gt; but serves as a marker to designate a class implementing it as having a specific property. An example is the Serializable interface, which marks a class as serializable.&lt;/li&gt;
&lt;li&gt;Marker interfaces define a type that is implemented by instances of the marked class, allowing compile-time error detection. They provide stronger type checking compared to marker annotations, which cannot define a type.&lt;/li&gt;
&lt;li&gt;If the marker applies only to classes and interfaces, and there is a possibility of writing methods that accept only objects with the marking, a marker interface should be used. This enables compile-time type checking. If there is no need for such methods or if the marker is part of a framework heavily using annotations, a marker annotation is more appropriate.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="lambdas-and-streams"&gt;Lambdas and streams&lt;/h2&gt;
&lt;h3 id="item-42-prefer-lambdas-to-anonymous-classes"&gt;Item 42: Prefer lambdas to anonymous classes&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Lambdas are concise expressions that can be used to create instances of functional interfaces, providing a more compact alternative to anonymous classes.&lt;/li&gt;
&lt;li&gt;Lambdas lack names and documentation, making them less suitable for complex computations or those exceeding a few lines.&lt;/li&gt;
&lt;li&gt;Anonymous classes are still necessary for creating instances of abstract classes or interfaces with multiple abstract methods. Lambdas cannot obtain a reference to themselves, unlike anonymous classes.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-43-prefer-method-references-to-lambdas"&gt;Item 43: Prefer method references to lambdas&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Method references offer a more concise alternative to lambdas. They allow you to refer to a method by name instead of providing a lambda expression. This is particularly useful when the lambda expression only calls a method without any additional logic. E.g.:
&lt;ul&gt;
&lt;li&gt;Method reference: &lt;code&gt;map.merge(key, 1, Integer::sum);&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Lambda expression: &lt;code&gt;service.execute(() -&amp;gt; action());&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;By using method references, you can eliminate the need to declare parameter names explicitly in the lambda expression.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-44-favor-the-use-of-standard-functional-interfaces"&gt;Item 44: Favor the use of standard functional interfaces&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Instead of using the Template Method pattern, which involves sub-classing and overriding methods, the modern approach is to provide static factories or constructors that accept function objects as parameters.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;java.util.function&lt;/code&gt; package provides a collection of standard functional interfaces for various use cases. When choosing a functional parameter type, it is recommended to use the standard functional interfaces instead of creating custom interfaces.&lt;/li&gt;
&lt;li&gt;Functional interfaces should be annotated with the &lt;code&gt;@FunctionalInterface&lt;/code&gt; annotation. This annotation serves as documentation, enforces the single abstract method requirement, and prevents accidental addition of abstract methods in the interface.&lt;/li&gt;
&lt;li&gt;In API design, it&amp;rsquo;s important to avoid overloading methods that take different functional interfaces in the same argument position. This can create ambiguity for clients, and it&amp;rsquo;s best to design the API to prevent this situation.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-45-use-streams-judiciously"&gt;Item 45: Use streams judiciously&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Streams were introduced in Java 8 as a way to perform bulk operations on sequences of data elements. A stream represents a sequence of elements, and a stream pipeline consists of a source stream, intermediate operations, and a terminal operation.&lt;/li&gt;
&lt;li&gt;The streams API provides a fluent API, allowing multiple operations to be chained together in a single expression. This enables concise and readable code.&lt;/li&gt;
&lt;li&gt;Overusing streams can make code harder to read and maintain.&lt;/li&gt;
&lt;li&gt;They have restrictions on accessing and modifying local variables and limited control flow capabilities.&lt;/li&gt;
&lt;li&gt;Streams are well-suited for tasks such as transforming elements, filtering, combining elements, accumulating into collections, and searching. If a computation requires access to corresponding elements from multiple stages of the pipeline, streams might not be the best choice.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-46-prefer-side-effect-free-functions-in-streams"&gt;Item 46: Prefer side-effect-free functions in streams&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The fundamental aspect of the streams paradigm is structuring computations as a sequence of transformations where each stage&amp;rsquo;s result is a pure function of the previous stage&amp;rsquo;s result. A pure function depends only on its input and does not have any side effects or modify any state.&lt;/li&gt;
&lt;li&gt;When using stream operations, both intermediate and terminal, it&amp;rsquo;s important to ensure that the function objects passed to them are free of side effects. This means they should not depend on mutable state or update any state.&lt;/li&gt;
&lt;li&gt;The correct usage of streams involves utilizing collectors, which encapsulate reduction strategies. Collectors can be used to gather elements into collections or create maps based on grouping or other criteria (e.g., &lt;code&gt;toList&lt;/code&gt;, &lt;code&gt;toSet&lt;/code&gt;, &lt;code&gt;toMap&lt;/code&gt;, &lt;code&gt;groupingBy&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;There are parallel and concurrent variants of collectors, such as &lt;code&gt;groupingByConcurrent&lt;/code&gt; and &lt;code&gt;toConcurrentMap&lt;/code&gt;, which efficiently handle parallel execution and produce &lt;code&gt;ConcurrentHashMap&lt;/code&gt; instances.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-47-prefer-collection-to-stream-as-a-return-type"&gt;Item 47: Prefer Collection to Stream as a return type&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;code&gt;for&lt;/code&gt; loop cannot be used to iterate over a stream, and it&amp;rsquo;s not possible to add elements to a stream. This makes streams less flexible than collections.
&lt;ul&gt;
&lt;li&gt;To enable iteration over a stream with a for-each loop, an adapter method can be created. The method converts a Stream to an Iterable, allowing for the use of for-each loops.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;When designing a public API that returns a sequence, it is important to consider users who may prefer stream pipelines or for-each loops. The Collection interface, being a subtype of Iterable and providing a stream method, is often the best choice for a return type. Arrays can also be used when appropriate.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-48-use-caution-when-making-streams-parallel"&gt;Item 48: Use caution when making streams parallel&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Simply adding the &lt;code&gt;parallel&lt;/code&gt; method to a stream pipeline does not guarantee improved performance. In some cases, it can lead to liveness failures, incorrect results, and unpredictable behavior.&lt;/li&gt;
&lt;li&gt;Performance gains from parallelism are most significant when working with data structures like &lt;code&gt;ArrayList&lt;/code&gt;, &lt;code&gt;HashMap&lt;/code&gt;, &lt;code&gt;HashSet&lt;/code&gt;, &lt;code&gt;ConcurrentHashMap&lt;/code&gt;, &lt;code&gt;arrays&lt;/code&gt;, &lt;code&gt;int&lt;/code&gt; ranges, and &lt;code&gt;long&lt;/code&gt; ranges. These data structures can be easily split into sub-ranges, enabling efficient work division among parallel threads.&lt;/li&gt;
&lt;li&gt;Parallelization should only be used as a performance optimization.&lt;/li&gt;
&lt;li&gt;Certain domains, such as machine learning and data processing, are well-suited for parallel speedups.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="methods"&gt;Methods&lt;/h2&gt;
&lt;h3 id="item-49-check-parameters-for-validity"&gt;Item 49: Check parameters for validity&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Clearly document the restrictions on parameter values in the method&amp;rsquo;s documentation. Enforce these restrictions by performing parameter checks at the beginning of the method body. Detecting errors as soon as possible is crucial for maintaining code integrity.&lt;/li&gt;
&lt;li&gt;If a method fails to check its parameters, it may result in confusing exceptions, incorrect results, or compromised object states.&lt;/li&gt;
&lt;li&gt;For public and protected methods, use the &lt;code&gt;@throws&lt;/code&gt; tag in Javadoc to document the exception that will be thrown if a parameter value violates a restriction.&lt;/li&gt;
&lt;li&gt;Use the &lt;code&gt;Objects.requireNonNull&lt;/code&gt; method, introduced in Java 7, to check for null values. It is flexible and convenient, allowing you to specify your own exception detail message if desired. It returns the non-null value, enabling simultaneous null check and usage.&lt;/li&gt;
&lt;li&gt;Nonpublic methods can use assertions to check parameters since the package author controls the method&amp;rsquo;s usage. Assertions throw AssertionError if the condition fails. Enabling assertions with the &lt;code&gt;-ea&lt;/code&gt; flag is necessary for assertions to take effect.&lt;/li&gt;
&lt;li&gt;While it&amp;rsquo;s important to check parameter validity, avoid imposing unnecessary restrictions on parameters. Design methods to be as general as possible, accepting a wide range of valid parameter values.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-50-make-defensive-copies-when-needed"&gt;Item 50: Make defensive copies when needed&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;To protect against ill-behaved clients or honest mistakes, it is crucial to write robust classes that can handle unexpected behavior.&lt;/li&gt;
&lt;li&gt;Classes that contain mutable objects can be vulnerable to attacks that exploit their mutability.&lt;/li&gt;
&lt;li&gt;make defensive copies of each mutable parameter in the constructor. Use these copies as components of the class instance instead of the original objects. This ensures that changes to the original objects do not affect the class&amp;rsquo;s internal state.&lt;/li&gt;
&lt;li&gt;Accessor methods that provide access to mutable internal fields should also return defensive copies of the fields.&lt;/li&gt;
&lt;li&gt;Whenever possible, use immutable objects as components of your classes to eliminate the need for defensive copying. Immutable objects are inherently safe and can simplify your code.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-51-design-method-signatures-carefully"&gt;Item 51: Design method signatures carefully&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Choose method names carefully.&lt;/li&gt;
&lt;li&gt;Avoid excessive convenience methods. Convenience methods are useful, but they can make the API more difficult to learn and maintain.&lt;/li&gt;
&lt;li&gt;Limit parameter list length.&lt;/li&gt;
&lt;li&gt;Prefer interfaces over classes for parameter types. Use interfaces to define parameters instead of specific classes whenever possible. This allows for more flexibility and enables the use of different implementations. For example, use the &lt;code&gt;Map&lt;/code&gt; interface instead of the &lt;code&gt;HashMap&lt;/code&gt; class to allow different &lt;code&gt;Map&lt;/code&gt; implementations to be used.&lt;/li&gt;
&lt;li&gt;Use enums instead of boolean parameters. Enums allow for future expansion by adding more options without changing method signatures.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-52-use-overloading-judiciously"&gt;Item 52: Use overloading judiciously&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Overloading can lead to unexpected behavior: If overloaded methods have the same number of parameters and the same compile-time type of the arguments, the selection of the method is ambiguous.&lt;/li&gt;
&lt;li&gt;Overloaded methods should have &amp;ldquo;radically different&amp;rdquo; parameter types.&lt;/li&gt;
&lt;li&gt;Generics can create situations where two overloadings with different functional interfaces in the same argument position cause confusion. It&amp;rsquo;s recommended not to overload methods that take different functional interfaces in the same argument position.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-53-use-varargs-judiciously"&gt;Item 53: Use varargs judiciously&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Varargs allow methods to accept a variable number of arguments of a specified type. They work by creating an array internally and passing the array to the method.&lt;/li&gt;
&lt;li&gt;Use varargs when you want a method with a variable number of arguments. For example, when calculating the sum of integers or finding the minimum of a set of integers.&lt;/li&gt;
&lt;li&gt;Declare the method to take two parameters: one normal parameter and one varargs parameter. This ensures that the method can handle both cases when at least one argument is passed and when more than one argument is passed.&lt;/li&gt;
&lt;li&gt;Be aware that every invocation of a varargs method causes an array allocation and initialization, so consider the performance implications in performance-critical situations.
&lt;ul&gt;
&lt;li&gt;To optimize performance while still using varargs, you can provide overloaded methods with a fixed number of parameters and a single varargs method for cases when the number of arguments exceeds a certain threshold.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-54-return-empty-collections-or-arrays-not-nulls"&gt;Item 54: Return empty collections or arrays, not nulls&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Returning null to indicate an empty collection or array is unnecessary and error-prone. It requires extra code in the client to handle the null return value and increases the risk of null pointer errors.&lt;/li&gt;
&lt;li&gt;Instead of returning null, return empty collections or arrays. This can be achieved by creating a new instance of the appropriate collection or array type. For example, returning &lt;code&gt;new ArrayList&amp;lt;&amp;gt;(cheesesInStock)&lt;/code&gt; will return an empty &lt;code&gt;ArrayList&lt;/code&gt; if &lt;code&gt;cheesesInStock&lt;/code&gt; is empty.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-55-return-optionals-judiciously"&gt;Item 55: Return optionals judiciously&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Exceptions should be reserved for exceptional conditions, and returning null requires special-case code to handle it and increases the risk of null pointer errors.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;Optional&amp;lt;T&amp;gt;&lt;/code&gt; class represents an immutable container that can hold either a single non-null value of type &lt;code&gt;T&lt;/code&gt; or nothing at all (empty). It provides a more flexible and less error-prone alternative to exceptions or null returns.&lt;/li&gt;
&lt;li&gt;Avoid using &lt;code&gt;Optional&amp;lt;T&amp;gt;&lt;/code&gt; for container types like collections, maps, streams, arrays, and other optionals. Return the empty container directly instead of wrapping it in an optional.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-56-write-doc-comments-for-all-exposed-api-elements"&gt;Item 56: Write doc comments for all exposed API elements&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Javadoc is a utility that generates API documentation automatically from specially formatted doc comments in the source code.&lt;/li&gt;
&lt;li&gt;Precede every exported class, interface, constructor, method, and field declaration with a doc comment. It describes the contract between the API element and its client.&lt;/li&gt;
&lt;li&gt;Document the preconditions, post-conditions, and side effects of methods. Use the &lt;code&gt;@param&lt;/code&gt; tag to describe parameters, &lt;code&gt;@return&lt;/code&gt; tag for the return value (if not void), and &lt;code&gt;@throws&lt;/code&gt; tag for exceptions thrown.&lt;/li&gt;
&lt;li&gt;Use HTML tags in doc comments to format and structure the generated documentation.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;{@code}&lt;/code&gt; tag to render code fragments in code font and to suppress processing of HTML markup and nested Javadoc tags within the code fragment.&lt;/li&gt;
&lt;li&gt;Write summary descriptions as &lt;em&gt;verb&lt;/em&gt; phrases for &lt;em&gt;methods and constructors&lt;/em&gt;, and &lt;em&gt;noun&lt;/em&gt; phrases for &lt;em&gt;classes&lt;/em&gt;, &lt;em&gt;interfaces&lt;/em&gt;, and &lt;em&gt;fields&lt;/em&gt;. The first sentence becomes the summary description.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;{@literal}&lt;/code&gt; tag to include HTML metacharacters in documentation, such as &lt;code&gt;&amp;lt;&lt;/code&gt;, &lt;code&gt;&amp;gt;&lt;/code&gt;, and &lt;code&gt;&amp;amp;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Document self-use patterns in classes designed for inheritance using the &lt;code&gt;@implSpec&lt;/code&gt; tag. It describes the contract between the method and its subclass.&lt;/li&gt;
&lt;li&gt;Package-level doc comments should be placed in &lt;code&gt;package-info.java&lt;/code&gt; file. Similarly, module-level comments should be placed in &lt;code&gt;module-info.java&lt;/code&gt; file.&lt;/li&gt;
&lt;li&gt;Document thread-safety and serializability of classes.&lt;/li&gt;
&lt;li&gt;Read the generated documentation to ensure clarity and make any necessary improvements to the doc comments.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="general-programming"&gt;General programming&lt;/h2&gt;
&lt;h3 id="item-57-minimize-the-scope-of-local-variables"&gt;Item 57: Minimize the scope of local variables&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Declare variables where they are first used, rather than at the beginning of a block. This approach eliminates clutter and helps readers understand the purpose and type of the variable when it is used.&lt;/li&gt;
&lt;li&gt;Avoid prematurely declaring variables outside of the block in which they are used. By doing so, you ensure that the variable&amp;rsquo;s scope begins at the appropriate point and ends when it is no longer needed.&lt;/li&gt;
&lt;li&gt;Take advantage of the scope-limiting capabilities of for loops.&lt;/li&gt;
&lt;li&gt;Prefer for loops over while loops when the loop variable is not needed after the loop terminates.&lt;/li&gt;
&lt;li&gt;Minimizing the scope of local variables helps prevent copy-and-paste errors.&lt;/li&gt;
&lt;li&gt;Consider using multiple loop variables within a for loop to avoid redundant computations. This approach can improve performance by storing the limit of the first variable in a second variable, eliminating the need for redundant computations in each iteration.&lt;/li&gt;
&lt;li&gt;Keep methods small and focused to minimize the scope of local variables.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-58-prefer-for-each-loops-to-traditional-for-loops"&gt;Item 58: Prefer &lt;code&gt;for-each&lt;/code&gt; loops to traditional &lt;code&gt;for&lt;/code&gt; loops&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Traditional &lt;code&gt;for&lt;/code&gt; loops for iteration over collections and arrays can be cluttered and prone to errors. They require explicit use of an iterator or an index variable.&lt;/li&gt;
&lt;li&gt;The for-each loop (enhanced for statement) solves these issues by eliminating the need for explicit iterators or index variables: &lt;code&gt;for (Element e : elements) { ... }&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;For-each loops can be used with both collections and arrays, making it easy to switch the implementation type of a container without changing the loop syntax.&lt;/li&gt;
&lt;li&gt;For nested iteration, for-each loops offer greater clarity and simplicity compared to traditional for loops. They avoid common bugs that can occur when using multiple iterators or index variables.&lt;/li&gt;
&lt;li&gt;There are certain situations where for-each loops cannot be used, such as when performing destructive filtering, transforming values, or iterating in parallel. In these cases, traditional for loops or other approaches may be necessary.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;Iterable&lt;/code&gt; interface allows objects to be iterated over using the for-each loop. By implementing the &lt;code&gt;Iterable&lt;/code&gt; interface and providing an iterator method, your custom types can be used with for-each loops.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-59-know-and-use-the-libraries"&gt;Item 59: Know and use the libraries&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Libraries, such as &lt;code&gt;Random&lt;/code&gt;, offer well-designed and thoroughly tested methods for common tasks.&lt;/li&gt;
&lt;li&gt;The use of libraries saves time and effort. You can focus on your application logic instead of spending time on low-level implementations.&lt;/li&gt;
&lt;li&gt;Standard libraries tend to improve over time in terms of performance and functionality.&lt;/li&gt;
&lt;li&gt;While the libraries are extensive, every programmer should be familiar with the basics of &lt;code&gt;java.lang&lt;/code&gt;, &lt;code&gt;java.util&lt;/code&gt;, &lt;code&gt;java.io&lt;/code&gt;, and their sub-packages. Additional knowledge can be acquired on an as-needed basis.&lt;/li&gt;
&lt;li&gt;Certain libraries, such as the collections framework, streams library, and concurrency utilities in &lt;code&gt;java.util.concurrent&lt;/code&gt;, should be part of every programmer&amp;rsquo;s toolkit.&lt;/li&gt;
&lt;li&gt;Avoid reinventing the wheel. If a common task can be accomplished using existing library facilities, utilize them instead of writing your own code. Library code is often more robust and undergoes more scrutiny than individual developers can afford.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-60-avoid-float-and-double-if-exact-answers-are-required"&gt;Item 60: Avoid float and double if exact answers are required&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;float&lt;/code&gt; and &lt;code&gt;double&lt;/code&gt; types are designed for scientific and engineering calculations and provide fast but approximate results using binary floating-point arithmetic.&lt;/li&gt;
&lt;li&gt;The inherent imprecision of float and double types makes them unsuitable for applications where exact results are necessary, such as monetary calculations.&lt;/li&gt;
&lt;li&gt;Performing arithmetic operations with float and double types can lead to unexpected rounding errors and inaccuracies.&lt;/li&gt;
&lt;li&gt;Rounding the results before printing is not a reliable solution to the imprecision issue.&lt;/li&gt;
&lt;li&gt;To achieve accurate results in monetary calculations, it is recommended to use alternative data types like &lt;code&gt;BigDecimal&lt;/code&gt;, &lt;code&gt;int&lt;/code&gt;, or &lt;code&gt;long&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;BigDecimal&lt;/code&gt; is a precise data type that can handle exact decimal calculations. It is suitable for situations where accuracy is paramount, such as monetary calculations. However, it is less convenient to use than primitive types and slower in performance.&lt;/li&gt;
&lt;li&gt;An alternative approach is to perform calculations in cents using int or long types, keeping track of the decimal point manually. This approach is more efficient and convenient than using &lt;code&gt;BigDecimal&lt;/code&gt; but has limitations in handling large quantities.&lt;/li&gt;
&lt;li&gt;Use BigDecimal when precision is critical, int or long when performance and convenience are important, and float or double when approximate results are acceptable.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;BigDecimal&lt;/code&gt; offers full control over rounding, which is useful in business calculations with legally mandated rounding behavior.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-61-prefer-primitive-types-to-boxed-primitives"&gt;Item 61: Prefer primitive types to boxed primitives&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Java has two types: primitives (e.g., &lt;code&gt;int&lt;/code&gt;, &lt;code&gt;double&lt;/code&gt;, &lt;code&gt;boolean&lt;/code&gt;) and reference types (e.g., &lt;code&gt;String&lt;/code&gt;, &lt;code&gt;List&lt;/code&gt;). Each primitive type has a corresponding boxed primitive type (e.g., &lt;code&gt;Integer&lt;/code&gt;, &lt;code&gt;Double&lt;/code&gt;, &lt;code&gt;Boolean&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Primitives only have values, while boxed primitives have both values and identities.&lt;/li&gt;
&lt;li&gt;Boxed primitives have an additional nonfunctional value: &lt;code&gt;null&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Primitives are more time- and space-efficient compared to boxed primitives.&lt;/li&gt;
&lt;li&gt;Comparing boxed primitives with the &lt;code&gt;==&lt;/code&gt; operator performs an identity comparison, not a value comparison.&lt;/li&gt;
&lt;li&gt;Auto-unboxing a null boxed primitive results in a NullPointerException.&lt;/li&gt;
&lt;li&gt;Auto-boxing and auto-unboxing operations can lead to unnecessary object creations and performance issues.&lt;/li&gt;
&lt;li&gt;Use primitives whenever possible, especially when comparing values or performing computations.&lt;/li&gt;
&lt;li&gt;Boxed primitives are necessary in specific situations:
&lt;ul&gt;
&lt;li&gt;When using collections, as primitives cannot be directly added to collections;&lt;/li&gt;
&lt;li&gt;As type parameters in parameterized types and methods;&lt;/li&gt;
&lt;li&gt;When making reflective method invocations.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-62-avoid-strings-where-other-types-are-more-appropriate"&gt;Item 62: Avoid strings where other types are more appropriate&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Strings should be used to represent text and should not be used as substitutes for other value types.&lt;/li&gt;
&lt;li&gt;Avoid using strings to represent numeric data. Translate numeric data into the appropriate numeric type, such as &lt;code&gt;int&lt;/code&gt;, &lt;code&gt;float&lt;/code&gt;, or &lt;code&gt;BigInteger&lt;/code&gt;, to ensure accuracy and enable numerical operations.&lt;/li&gt;
&lt;li&gt;Enum types are better suited for enumerated type constants than strings. Use enums to represent a fixed set of values with distinct identities and behaviors.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-63-beware-the-performance-of-string-concatenation"&gt;Item 63: Beware the performance of string concatenation&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The string concatenation operator is convenient for combining a few strings but does not scale well. When using the concatenation operator repeatedly, the time required is quadratic in the number of strings being concatenated because the contents of both strings are copied each time.&lt;/li&gt;
&lt;li&gt;To achieve better performance, use a &lt;code&gt;StringBuilder&lt;/code&gt; instead of the string concatenation operator when constructing a string from multiple components. &lt;code&gt;StringBuilder&lt;/code&gt; provides efficient appending of strings, and its performance is linear in the number of strings being concatenated.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;StringBuilder&lt;/code&gt; approach can significantly outperform the string concatenation operator, especially when the number of strings or the size of the resulting string is large. Preallocating a &lt;code&gt;StringBuilder&lt;/code&gt; with an appropriate capacity further improves performance by avoiding automatic growth.&lt;/li&gt;
&lt;li&gt;Consider alternatives to string concatenation, such as using a character array or processing strings individually instead of combining them if performance is a concern.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-64-refer-to-objects-by-their-interfaces"&gt;Item 64: Refer to objects by their interfaces&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Favor using interfaces as types over classes when referring to objects. Parameters, return values, variables, and fields should all be declared using interface types if appropriate interfaces exist.&lt;/li&gt;
&lt;li&gt;By using interfaces as types, your code becomes more flexible. If you decide to switch implementations, you can simply change the class name in the constructor (or use a different static factory) without affecting the surrounding code.&lt;/li&gt;
&lt;li&gt;It is appropriate to refer to objects by their class rather than an interface when no appropriate interface exists, such as with value classes like &lt;code&gt;String&lt;/code&gt; or &lt;code&gt;BigInteger&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Classes implementing an interface but providing additional methods not found in the interface should be referred to by their class only if the program relies on those extra methods.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-65-prefer-interfaces-to-reflection"&gt;Item 65: Prefer interfaces to reflection&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Reflection provides programmatic access to arbitrary classes and allows manipulation of their constructors, methods, and fields. However, it comes with several drawbacks:
&lt;ul&gt;
&lt;li&gt;Loss of compile-time type checking and exception checking;&lt;/li&gt;
&lt;li&gt;Clumsy and verbose code required for reflective access;&lt;/li&gt;
&lt;li&gt;Poor performance compared to normal method invocation.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Reflection is rarely needed in most applications.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-66-use-native-methods-judiciously"&gt;Item 66: Use native methods judiciously&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The use of native methods has serious disadvantages:
&lt;ul&gt;
&lt;li&gt;Native languages are not memory safe, so applications using native methods are susceptible to memory corruption errors;&lt;/li&gt;
&lt;li&gt;Native methods make programs less portable as they are more platform-dependent than Java;&lt;/li&gt;
&lt;li&gt;Debugging native code is more challenging compared to Java code;&lt;/li&gt;
&lt;li&gt;Garbage collection and memory management become more complex since the garbage collector cannot track or automate native memory usage;&lt;/li&gt;
&lt;li&gt;Native methods require writing and maintaining &amp;ldquo;glue code,&amp;rdquo; which can be difficult to read and tedious to write.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use as little native code as possible.&lt;/li&gt;
&lt;li&gt;Thoroughly test the native code to avoid bugs that could corrupt the entire application.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-67-optimize-judiciously"&gt;Item 67: Optimize judiciously&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Premature optimization is often counterproductive. More computing sins are committed in the name of efficiency than for any other reason. Optimization without necessarily achieving it can lead to software that is neither fast nor correct and can be difficult to fix.&lt;/li&gt;
&lt;li&gt;Good programs should prioritize sound architectural principles over performance. Write good programs first, and if necessary, optimize them later. Good programs are designed with information hiding, allowing individual components to be changed without affecting the rest of the system.&lt;/li&gt;
&lt;li&gt;Performance should be considered during the design process. Avoid design decisions that limit performance, especially in APIs, wire-level protocols, and persistent data formats. API design can have a significant impact on performance, so be mindful of decisions such as mutability, inheritance, and interface usage.&lt;/li&gt;
&lt;li&gt;API design and architectural decisions can have real performance consequences. Consider the trade-offs and implications of your design choices. For example, returning mutable objects may result in unnecessary defensive copying, and using implementation types instead of interfaces can limit future performance improvements.&lt;/li&gt;
&lt;li&gt;Before optimizing, ensure that your program has a clear, concise, and well-structured implementation. Measure performance before and after each attempted optimization. Profiling tools can help identify performance bottlenecks and guide optimization efforts. Be aware that Java&amp;rsquo;s performance model is less well-defined compared to lower-level languages, making it essential to measure the effects of optimizations on different implementations and hardware platforms.&lt;/li&gt;
&lt;li&gt;Algorithmic changes should be prioritized over low-level optimizations. If a quadratic or inefficient algorithm exists, no amount of tuning will fix the underlying problem.&lt;/li&gt;
&lt;li&gt;Performance measurement and optimization are iterative processes. Measure performance, identify bottlenecks, optimize relevant parts, and repeat until satisfied.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-68-adhere-to-generally-accepted-naming-conventions"&gt;Item 68: Adhere to generally accepted naming conventions&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Typographical Naming Conventions:
&lt;ul&gt;
&lt;li&gt;Package and module names should be hierarchical, separated by periods, and consist of lowercase alphabetic characters and digits. The name should begin with the organization&amp;rsquo;s Internet domain name, with the components reversed;&lt;/li&gt;
&lt;li&gt;Class and interface names should consist of one or more words, with the first letter of each word capitalized. Abbreviations should be avoided, except for acronyms and common abbreviations.&lt;/li&gt;
&lt;li&gt;Method and field names should follow the same typographical conventions as class and interface names, with the first letter lowercase for methods and fields. Acronyms occurring as the first word should be lowercase;&lt;/li&gt;
&lt;li&gt;Constant field names should consist of uppercase words separated by underscores;&lt;/li&gt;
&lt;li&gt;Local variable names follow similar conventions to member names, with abbreviations and short sequences of characters permitted.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Grammatical Naming Conventions:
&lt;ul&gt;
&lt;li&gt;Instantiable classes are generally named with a singular noun or noun phrase. Non-instantiable utility classes are often named with a plural noun;&lt;/li&gt;
&lt;li&gt;Interfaces are named like classes or with an adjective ending in &amp;ldquo;able&amp;rdquo; or &amp;ldquo;ible&amp;rdquo;;&lt;/li&gt;
&lt;li&gt;Methods that perform actions are named with a verb or verb phrase. Methods returning boolean values usually begin with &amp;ldquo;is&amp;rdquo; or &amp;ldquo;has&amp;rdquo;;&lt;/li&gt;
&lt;li&gt;Methods returning non-boolean values or attributes of the object are usually named with a noun, noun phrase, or a verb phrase beginning with &amp;ldquo;get&amp;rdquo;;&lt;/li&gt;
&lt;li&gt;Field names typically follow the same conventions as class and interface names, using nouns or noun phrases.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="exceptions"&gt;Exceptions&lt;/h2&gt;
&lt;h3 id="item-69-use-exceptions-only-for-exceptional-conditions"&gt;Item 69: Use exceptions only for exceptional conditions&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Exceptions should be used for exceptional circumstances, situations that are uncommon and unexpected. They should not be used for regular control flow.&lt;/li&gt;
&lt;li&gt;Exceptions are not designed to be as fast as explicit tests, so using them for control flow can result in slower code execution.&lt;/li&gt;
&lt;li&gt;Placing code inside a try-catch block inhibits certain optimizations that JVM implementations may perform.&lt;/li&gt;
&lt;li&gt;The exception-based loop, which relies on throwing and catching exceptions for loop termination, is slower, obfuscates the code&amp;rsquo;s purpose, and can hide bugs in the code.&lt;/li&gt;
&lt;li&gt;Exceptions used for control flow can mask bugs, making debugging more complicated. Bugs that would generate uncaught exceptions in a standard loop idiom may be caught and misinterpreted as normal loop termination in an exception-based loop.&lt;/li&gt;
&lt;li&gt;An alternative to a state-testing method is to have the state-dependent method return an empty optional or a distinguished value (such as null) if it cannot perform the desired computation.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-70-use-checked-exceptions-for-recoverable-conditions-and-runtime-exceptions-for-programming-errors"&gt;Item 70: Use checked exceptions for recoverable conditions and runtime exceptions for programming errors&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Checked exceptions should be used for conditions from which the caller can reasonably be expected to recover. By throwing a checked exception, the API designer mandates the caller to handle the exception or propagate it.&lt;/li&gt;
&lt;li&gt;Checked exceptions indicate recoverable conditions, and the API user should make an effort to handle them appropriately.&lt;/li&gt;
&lt;li&gt;Unchecked throwables, which include runtime exceptions and errors, needn&amp;rsquo;t and generally shouldn&amp;rsquo;t be caught. They indicate situations where recovery is impossible, and continued execution would do more harm than good.&lt;/li&gt;
&lt;li&gt;Runtime exceptions are typically used to indicate programming errors, such as precondition violations.&lt;/li&gt;
&lt;li&gt;It may not always be clear whether a condition is recoverable or a programming error. In such cases, it is a matter of judgment for the API designer. If recovery is likely, use a checked exception; if not, use a runtime exception.&lt;/li&gt;
&lt;li&gt;Checked exceptions should provide methods that aid in recovery from the exceptional condition.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-71-avoid-unnecessary-use-of-checked-exceptions"&gt;Item 71: Avoid unnecessary use of checked exceptions&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Overuse of checked exceptions can make APIs difficult to use.&lt;/li&gt;
&lt;li&gt;The burden on the programmer increases when dealing with checked exceptions, as they must be handled in catch blocks or propagated outward, placing a burden on the API user.&lt;/li&gt;
&lt;li&gt;Another approach is to refactor the method that throws the checked exception into two methods: one that returns a boolean indicating whether the exception would be thrown and another that performs the action. This allows the caller to check the state before invoking the action method.&lt;/li&gt;
&lt;li&gt;Use checked exceptions sparingly, consider returning optionals, and throw unchecked exceptions if recovery is not possible or meaningful for the caller.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-72-favor-the-use-of-standard-exceptions"&gt;Item 72: Favor the use of standard exceptions&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Reusing standard exceptions in your APIs and programs provides several benefits, including easier learning and usage, improved readability, and reduced memory footprint and class loading time.&lt;/li&gt;
&lt;li&gt;The most commonly reused exception types are &lt;code&gt;IllegalArgumentException&lt;/code&gt; and &lt;code&gt;IllegalStateException&lt;/code&gt;. &lt;code&gt;IllegalArgumentException&lt;/code&gt; is used when the caller passes an &lt;em&gt;inappropriate argument value&lt;/em&gt;, while &lt;code&gt;IllegalStateException&lt;/code&gt; is used when the invocation is &lt;em&gt;illegal due to the state of the receiving object&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;It is recommended to use specific standard exceptions like &lt;code&gt;NullPointerException&lt;/code&gt; and &lt;code&gt;IndexOutOfBoundsException&lt;/code&gt; for certain kinds of illegal arguments and states instead of using &lt;code&gt;IllegalArgumentException&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;ConcurrentModificationException is a reusable exception used to indicate concurrent modification of an object that was designed for single-threaded use or with external synchronization.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;UnsupportedOperationException&lt;/code&gt; is another reusable exception used to indicate that an object does not support a particular operation, typically because it is an optional operation defined by an interface that the object implements.It is advised not to reuse the &lt;code&gt;Exception&lt;/code&gt;, &lt;code&gt;RuntimeException&lt;/code&gt;, &lt;code&gt;Throwable&lt;/code&gt;, or &lt;code&gt;Error&lt;/code&gt; classes directly. Treat them as abstract and avoid testing for them directly because they are superclasses of other exceptions.&lt;/li&gt;
&lt;li&gt;When reusing exceptions, ensure that the conditions under which you would throw them align with their documented semantics. You can subclass a standard exception to add more detail if needed.&lt;/li&gt;
&lt;li&gt;Choosing which exception to reuse can be challenging when multiple exceptions seem applicable. In such cases, follow the rule to throw &lt;code&gt;IllegalStateException&lt;/code&gt; if no argument values would have worked, otherwise throw &lt;code&gt;IllegalArgumentException&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-73-throw-exceptions-appropriate-to-the-abstraction"&gt;Item 73: Throw exceptions appropriate to the abstraction&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Higher layers should catch lower-level exceptions and throw exceptions that are meaningful and can be explained in terms of the higher-level abstraction. This is known as &lt;em&gt;exception translation&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Exception translation&lt;/em&gt; is achieved by catching the lower-level exception and throwing a higher-level exception that encapsulates the lower-level exception and provides a more meaningful explanation of the problem.&lt;/li&gt;
&lt;li&gt;Exception chaining is a special form of exception translation where the lower-level exception is passed to the higher-level exception as the cause. This allows for easy access to the lower-level exception and integration of its stack trace into the higher-level exception&amp;rsquo;s stack trace.&lt;/li&gt;
&lt;li&gt;Exception translation should not be overused. Whenever possible, exceptions from lower layers should be prevented or handled within the higher layer itself.&lt;/li&gt;
&lt;li&gt;If exceptions from lower layers cannot be prevented or handled, it may be appropriate for the higher layer to silently work around these exceptions, log them using an appropriate logging facility, and insulate the caller from lower-level problems.&lt;/li&gt;
&lt;li&gt;Exception translation allows for better encapsulation, clearer APIs, and the ability to investigate the underlying cause of failures while insulating clients from lower-level exceptions.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-74-document-all-exceptions-thrown-by-each-method"&gt;Item 74: Document all exceptions thrown by each method&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Documenting the exceptions thrown by a method is a critical part of the documentation required to use the method correctly.&lt;/li&gt;
&lt;li&gt;Always declare checked exceptions individually and document the specific conditions under which each exception is thrown using the Javadoc &lt;code&gt;@throws&lt;/code&gt; tag.&lt;/li&gt;
&lt;li&gt;While the language does not require documenting unchecked exceptions, it is wise to document them carefully as they often represent programming errors. Familiarizing programmers with all the possible errors helps them avoid making these mistakes.&lt;/li&gt;
&lt;li&gt;Do not use the &lt;code&gt;throws&lt;/code&gt; keyword on unchecked exceptions.&lt;/li&gt;
&lt;li&gt;It is ideal to document all unchecked exceptions that each method can throw, but in practice, it may not always be achievable due to dependencies on other classes that may throw additional unchecked exceptions.&lt;/li&gt;
&lt;li&gt;If an exception is thrown by many methods in a class for the same reason, you can document the exception in the class&amp;rsquo;s documentation comment instead of documenting it individually for each method.&lt;/li&gt;
&lt;li&gt;Failing to document the exceptions that your methods can throw can make it difficult or impossible for others to effectively use your classes and interfaces.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-75-include-failure-capture-information-in-detail-messages"&gt;Item 75: Include failure-capture information in detail messages&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The detail message of an exception should capture as much information as possible concerning the cause of the failure. It should contain the values of all parameters and fields that contributed to the exception.&lt;/li&gt;
&lt;li&gt;Including pertinent data in the detail message aids in diagnosing the cause of the failure. It helps identify specific errors such as incorrect index values, boundary violations, or invariant failures.&lt;/li&gt;
&lt;li&gt;It is crucial to avoid including security-sensitive information like passwords or encryption keys in exception detail messages as stack traces may be seen by multiple individuals during the debugging and issue-fixing process.&lt;/li&gt;
&lt;li&gt;Do not write lengthy prose descriptions.&lt;/li&gt;
&lt;li&gt;The detail message of an exception is primarily intended for programmers or site reliability engineers, not end users. Therefore, information content is more important than readability.&lt;/li&gt;
&lt;li&gt;Requiring failure-capture information as parameters in the constructors of exceptions can ensure that the detail message automatically includes the necessary information. This centralizes the code for generating a high-quality detail message in the exception class itself.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-76-strive-for-failure-atomicity"&gt;Item 76: Strive for failure atomicity&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Failure atomicity means that after an object throws an exception, it should still be in a well-defined, usable state, even if the failure occurred in the midst of performing an operation.&lt;/li&gt;
&lt;li&gt;Immutable objects naturally achieve failure atomicity because their state is consistent when they are created and cannot be modified thereafter.&lt;/li&gt;
&lt;li&gt;For methods that operate on mutable objects, one way to achieve failure atomicity is to check parameters for validity before performing the operation. This ensures that most exceptions are thrown before object modification commences.&lt;/li&gt;
&lt;li&gt;Another approach to achieving failure atomicity is to order the computation so that any part that may fail takes place before any part that modifies the object. This ensures that failure occurs before any modification to the object.&lt;/li&gt;
&lt;li&gt;A third approach is to perform the operation on a temporary copy of the object and replace the contents of the object with the temporary copy once the operation is complete. This is useful when the computation can be performed more efficiently on a temporary data structure.&lt;/li&gt;
&lt;li&gt;Recovery code can be written to intercept a failure and roll back the object&amp;rsquo;s state to the point before the operation began. This approach is mainly used for durable data structures.&lt;/li&gt;
&lt;li&gt;Failure atomicity is not always achievable, especially in cases of concurrent modification without proper synchronization. In such cases, objects may be left in an inconsistent state.&lt;/li&gt;
&lt;li&gt;It is not always desirable or practical to achieve failure atomicity, as it can increase cost and complexity. However, it is often easy to achieve once the issue is understood.&lt;/li&gt;
&lt;li&gt;API documentation should clearly indicate whether failure atomicity is achieved and what state the object will be left in after a method invocation.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-77-dont-ignore-exceptions"&gt;Item 77: Don&amp;rsquo;t ignore exceptions&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;When an API declares a method to throw an exception, it is indicating that there may be exceptional conditions that need to be handled.&lt;/li&gt;
&lt;li&gt;Ignoring exceptions by surrounding a method invocation with an empty catch block defeats the purpose of exceptions and can lead to disastrous results.&lt;/li&gt;
&lt;li&gt;Ignoring exceptions is like ignoring a fire alarm and preventing others from addressing the problem. It is important to handle exceptional conditions appropriately.&lt;/li&gt;
&lt;li&gt;There are situations where it may be appropriate to ignore an exception, such as when closing a file input stream where no recovery action is needed and the operation can proceed without issues.&lt;/li&gt;
&lt;li&gt;If an exception is intentionally ignored, the catch block should contain a comment explaining the reason for ignoring it, and the variable used to catch the exception should be named &lt;code&gt;ignored&lt;/code&gt; to indicate that it is intentionally disregarded.&lt;/li&gt;
&lt;li&gt;Ignoring exceptions can lead to a program that continues silently despite errors, potentially causing failures at unexpected points in the code.&lt;/li&gt;
&lt;li&gt;Letting exceptions propagate outward can at least result in a swift failure, preserving information for debugging purposes.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="concurrency"&gt;Concurrency&lt;/h2&gt;
&lt;h3 id="item-78-synchronize-access-to-shared-mutable-data"&gt;Item 78: Synchronize access to shared mutable data&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Synchronization ensures that only one thread can execute a synchronized method or block at a time, preventing an object from being seen in an inconsistent state by other threads.&lt;/li&gt;
&lt;li&gt;Synchronization not only guarantees mutual exclusion but also ensures that changes made by one thread are visible to other threads. It provides reliable communication between threads.&lt;/li&gt;
&lt;li&gt;Reading and writing a variable (other than long or double) is atomic, but it does not guarantee that changes made by one thread will be immediately visible to other threads without synchronization.&lt;/li&gt;
&lt;li&gt;Failing to synchronize access to shared mutable data can have dire consequences, even if the data is atomically readable and writable. It can lead to liveness failures and data corruption.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;java.util.concurrent.atomic&lt;/code&gt; package provides lock-free, thread-safe primitives, such as &lt;code&gt;AtomicLong&lt;/code&gt;, for performing atomic operations on single variables, which can be used as a more efficient alternative to synchronized methods.&lt;/li&gt;
&lt;li&gt;The best approach to avoid synchronization issues is to minimize sharing of mutable data. Either use immutable data or confine mutable data to a single thread. If sharing is necessary, ensure proper synchronization or use safe publication techniques.&lt;/li&gt;
&lt;li&gt;Safe publication involves ensuring that an object reference is safely shared with other threads by using techniques such as storing it in a static field during class initialization or using volatile or final fields.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-79-avoid-excessive-synchronization"&gt;Item 79: Avoid excessive synchronization&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Excessive synchronization can lead to reduced performance, deadlocks, or nondeterministic behavior.&lt;/li&gt;
&lt;li&gt;Excessive synchronization should be avoided for performance reasons. Excessive locking can lead to contention and limit parallelism, as well as hinder the VM&amp;rsquo;s ability to optimize code execution.&lt;/li&gt;
&lt;li&gt;Avoid unnecessary synchronization for mutable classes and document that they are not thread-safe if synchronization is omitted.&lt;/li&gt;
&lt;li&gt;If a method modifies a static field and can be called from multiple threads, synchronize access to the field internally to prevent data corruption and ensure deterministic behavior.&lt;/li&gt;
&lt;li&gt;Consider advanced synchronization techniques such as lock splitting, lock striping, and nonblocking concurrency control to achieve high concurrency when internal synchronization is necessary.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-80-prefer-executors-tasks-and-streams-to-threads"&gt;Item 80: Prefer executors, tasks, and streams to threads&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;java.util.concurrent&lt;/code&gt; package introduced the &lt;code&gt;Executor&lt;/code&gt; Framework, which provides a flexible interface-based task execution facility. It is recommended to use executors instead of writing your own work queues.&lt;/li&gt;
&lt;li&gt;Creating an executor service is as simple as calling a static factory method. For example, &lt;code&gt;Executors.newSingleThreadExecutor()&lt;/code&gt; creates an executor service with a single background thread.&lt;/li&gt;
&lt;li&gt;Tasks can be submitted for execution using the &lt;code&gt;execute()&lt;/code&gt; method of the executor service. The executor service takes care of managing the execution of tasks.&lt;/li&gt;
&lt;li&gt;To gracefully terminate the executor service, the &lt;code&gt;shutdown()&lt;/code&gt; method should be called. This ensures that the executor service will complete any pending tasks before exiting.&lt;/li&gt;
&lt;li&gt;The executor service provides various additional functionalities, such as waiting for specific tasks or collections of tasks to complete, scheduling tasks to run at specific times, retrieving task results, and more.&lt;/li&gt;
&lt;li&gt;Java provides static factory methods in the &lt;code&gt;Executors&lt;/code&gt; class that offer different types of executor services, such as cached thread pools, fixed thread pools, and scheduled thread pools. These cover most use cases, but the &lt;code&gt;ThreadPoolExecutor&lt;/code&gt; class allows fine-grained control over thread pool configuration.&lt;/li&gt;
&lt;li&gt;Choosing the right executor service depends on the specific requirements of the application. For small programs or lightly loaded servers, &lt;code&gt;Executors.newCachedThreadPool()&lt;/code&gt; is often sufficient. For heavily loaded production servers, &lt;code&gt;Executors.newFixedThreadPool()&lt;/code&gt; or ThreadPoolExecutor with custom configuration is recommended.&lt;/li&gt;
&lt;li&gt;The executor framework separates the unit of work (tasks) from the mechanism of executing it (executor service). This separation provides flexibility in selecting appropriate execution policies and allows easy changes if requirements evolve.&lt;/li&gt;
&lt;li&gt;Working directly with threads is discouraged. Instead, think in terms of tasks and let the executor service execute them. This approach allows you to leverage the flexibility and control provided by the executor framework.&lt;/li&gt;
&lt;li&gt;For a comprehensive understanding of the Executor Framework, it is recommended to refer to the book &lt;a href="https://jcip.net/"&gt;Java Concurrency in Practice&lt;/a&gt; by Brian Goetz.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-81-prefer-concurrency-utilities-to-wait-and-notify"&gt;Item 81: Prefer concurrency utilities to &lt;code&gt;wait&lt;/code&gt; and &lt;code&gt;notify&lt;/code&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The higher-level concurrency utilities fall into three categories: the Executor Framework (covered in Item 80), concurrent collections, and synchronizers.&lt;/li&gt;
&lt;li&gt;Concurrent collections are high-performance implementations of standard collection interfaces that internally manage their own synchronization. They provide high concurrency and state-dependent modify operations, making them ideal for concurrent applications.&lt;/li&gt;
&lt;li&gt;Synchronizers are objects that enable threads to coordinate their activities. Examples include &lt;code&gt;CountDownLatch&lt;/code&gt;, &lt;code&gt;Semaphore&lt;/code&gt;, &lt;code&gt;CyclicBarrier&lt;/code&gt;, and &lt;code&gt;Phaser&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The concurrent utilities provide high-level abstractions that simplify common concurrency scenarios. For example, a &lt;code&gt;ConcurrentHashMap&lt;/code&gt; can be used to implement a thread-safe canonicalizing map, and a &lt;code&gt;BlockingQueue&lt;/code&gt; can be used as a work queue for producer-consumer scenarios.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-82-document-thread-safety"&gt;Item 82: Document thread safety&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Thread safety, or how a class behaves when its methods are used concurrently, is an important part of its contract with clients.&lt;/li&gt;
&lt;li&gt;Failing to document the thread safety aspect of a class can lead to incorrect assumptions about synchronization, resulting in serious errors.&lt;/li&gt;
&lt;li&gt;The private lock object should be declared final to prevent accidental un-synchronized access and is particularly useful for classes designed for inheritance.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-83-use-lazy-initialization-judiciously"&gt;Item 83: Use lazy initialization judiciously&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Lazy initialization can be used to optimize the cost of initializing a class or creating an instance by deferring the initialization of a field until it is accessed.&lt;/li&gt;
&lt;li&gt;Lazy initialization should only be used when necessary, as it can increase the cost of accessing the lazily initialized field.&lt;/li&gt;
&lt;li&gt;Measure the performance impact of lazy initialization to determine whether it is beneficial for a specific scenario.&lt;/li&gt;
&lt;li&gt;In the presence of multiple threads, lazy initialization requires synchronization to avoid bugs.&lt;/li&gt;
&lt;li&gt;Normal initialization with the final modifier is usually preferable to lazy initialization for most fields.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-84-dont-depend-on-the-thread-scheduler"&gt;Item 84: Don&amp;rsquo;t depend on the thread scheduler&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The thread scheduler determines which threads get to run and for how long when many threads are runnable. However, the thread-scheduling policy can vary between operating systems, so relying on specific details of the policy can lead to non-portable programs.&lt;/li&gt;
&lt;li&gt;To write a robust, responsive, and portable program, aim to keep the average number of runnable threads close to the number of processors. This minimizes variations in behavior caused by different thread-scheduling policies.&lt;/li&gt;
&lt;li&gt;To keep the number of runnable threads low, ensure that each thread does some useful work and then waits for more. Thread pools should be sized appropriately, and tasks should be neither too short nor too long to avoid dispatch overhead.&lt;/li&gt;
&lt;li&gt;Avoid busy-waiting, where threads repeatedly check a shared object waiting for its state to change. Busy-waiting puts unnecessary load on the processor and reduces the amount of useful work that can be accomplished. It also makes the program vulnerable to the thread scheduler&amp;rsquo;s behavior.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="serialization"&gt;Serialization&lt;/h2&gt;
&lt;h3 id="item-85-prefer-alternatives-to-java-serialization"&gt;Item 85: Prefer alternatives to Java serialization&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Serialization in Java has proven to be risky, with problems related to correctness, performance, security, and maintenance.&lt;/li&gt;
&lt;li&gt;The attack surface of serialization is significant and constantly growing. Deserializing objects can execute code from any type on the classpath, making it vulnerable to exploits.&lt;/li&gt;
&lt;li&gt;Security researchers have discovered and exploited vulnerabilities in deserialization, leading to serious attacks, such as the SFMTA Muni ransomware attack.&lt;/li&gt;
&lt;li&gt;Deserialization bombs can be used to mount denial-of-service attacks by causing deserialization of byte streams that take a long time to process.&lt;/li&gt;
&lt;li&gt;The best defense against serialization exploits is to avoid deserializing untrusted data altogether. Serialization should be replaced with alternative mechanisms for translating objects to byte sequences.&lt;/li&gt;
&lt;li&gt;Cross-platform structured-data representations like JSON and Protocol Buffers offer advantages such as portability, high performance, tooling support, and a large community.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-86-implement-serializable-with-great-caution"&gt;Item 86: Implement &lt;code&gt;Serializable&lt;/code&gt; with great caution&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Implementing Serializable has long-term costs, as the serialized form of a class becomes part of its exported API. Changing the class&amp;rsquo;s internal representation while maintaining compatibility with the serialized form can be challenging and may limit the class&amp;rsquo;s evolution.&lt;/li&gt;
&lt;li&gt;Serialization introduces the risk of bugs and security vulnerabilities. Deserialization acts as a &amp;ldquo;hidden constructor&amp;rdquo; and must guarantee invariants established by constructors, while also preventing unauthorized access to object internals.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-87-consider-using-a-custom-serialized-form"&gt;Item 87: Consider using a custom serialized form&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;When the default serialized form is inappropriate for a class, it can result in several disadvantages, such as permanently tying the API to the current internal representation, consuming excessive space and time during serialization, and potentially causing stack overflows.&lt;/li&gt;
&lt;li&gt;Regardless of the serialized form chosen, any synchronization imposed on the object&amp;rsquo;s methods should also apply to the &lt;code&gt;writeObject&lt;/code&gt; method to prevent resource-ordering deadlocks.&lt;/li&gt;
&lt;li&gt;Taking the time to design a custom serialized form that accurately represents the logical data and excludes unnecessary implementation details can lead to more flexible, efficient, and maintainable serialization. The default serialized form should only be accepted if it aligns well with the class&amp;rsquo;s logical state.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-88-write-readobject-methods-defensively"&gt;Item 88: Write &lt;code&gt;readObject&lt;/code&gt; methods defensively&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;readObject&lt;/code&gt; method is similar to a public constructor for deserializing objects, and it requires the same care as any other constructor to ensure the object&amp;rsquo;s validity and invariants.&lt;/li&gt;
&lt;li&gt;To prevent invalid objects from being deserialized, the &lt;code&gt;readObject&lt;/code&gt; method should perform validity checks after calling &lt;code&gt;defaultReadObject&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-89-for-instance-control-prefer-enum-types-to-readresolve"&gt;Item 89: For instance control, prefer enum types to &lt;code&gt;readResolve&lt;/code&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;When a class is serialized and deserialized, the &lt;code&gt;readResolve&lt;/code&gt; method can be used to substitute another instance for the one created during deserialization.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;readResolve&lt;/code&gt; method can be implemented in a singleton class to return the original singleton instance and maintain the singleton property during deserialization.&lt;/li&gt;
&lt;li&gt;The preferred approach for instance control is to use an enum type. Enum types guarantee that only the declared constants are the instances of the class, preventing any additional instances from being created during deserialization.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="item-90-consider-serialization-proxies-instead-of-serialized-instances"&gt;Item 90: Consider serialization proxies instead of serialized instances&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The serialization proxy pattern involves designing a private static nested class, called the serialization proxy, that represents the logical state of the enclosing class in a concise manner.&lt;/li&gt;
&lt;li&gt;The serialization proxy should have a single constructor that takes the enclosing class as a parameter and copies its data without performing any consistency checking or defensive copying.&lt;/li&gt;
&lt;li&gt;Both the enclosing class and its serialization proxy should implement the &lt;code&gt;Serializable&lt;/code&gt; interface.&lt;/li&gt;
&lt;li&gt;The serialization proxy pattern eliminates the need for explicit field-level validation during deserialization and ensures that the invariants of the enclosing class are maintained.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;While I did not find this book to be particularly entertaining, it is a very useful reference for Java developers. It covers a wide range of topics and provides a lot of useful information. I would recommend this book to anyone who is interested in learning more about the Java language and its best practices.&lt;/p&gt;
&lt;h2 id="resources-and-references"&gt;Resources and references&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.oreilly.com/library/view/effective-java-3rd/9780134686097/"&gt;Effective Java, Third Edition&lt;/a&gt; - Joshua Bloch.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://jcip.net/"&gt;Java Concurrency in Practice&lt;/a&gt; - Brian Goetz.&lt;/li&gt;
&lt;/ul&gt;</content:encoded><dc:creator>Sébastien Lavoie</dc:creator><pubDate>Sun, 11 Jun 2023 18:15:00 -0600</pubDate><guid isPermaLink="false">https://www.sglavoie.com/posts/book-summary-effective-java/</guid><category>learnings</category><category>best practices</category><category>books</category><category>java</category></item><item><title>Book summary: The Effective Engineer</title><link>https://www.sglavoie.com/posts/book-summary-the-effective-engineer/</link><description>After reading Letters to a New Developer, one of the next logical steps on this learning path was to read [The Effective Engineer][effective-website]. I hope you enjoy this simple yet effective book summary!</description><content:encoded>&lt;hr&gt;
&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;
&lt;p&gt;This wonderful, mostly non-technical book is a compilation of the best practices and lessons learned by the author, &lt;a href="https://edmondlau.co/"&gt;Edmond Lau&lt;/a&gt;, during his impressive career as a software engineer. It is a must-read for anyone who wants to improve their skills and become more effective at what they do. The following are short excerpts from the condensed knowledge found in the book, sprinkled with some minor comments of my own along the way. These are extracted from the book’s takeaway sections and headings: I wholeheartedly recommend &lt;a href="https://www.effectiveengineer.com/"&gt;reading the work&lt;/a&gt; in its entirety for an immersive exposure to the fantastic storytelling capabilities of Edmond!&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="book-summary"&gt;Book summary&lt;/h2&gt;
&lt;h2 id="part-1-adopt-the-right-mindset"&gt;Part 1: Adopt the Right Mindset&lt;/h2&gt;
&lt;h3 id="focus-on-high-leverage-activities"&gt;Focus on high-leverage activities&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;Leverage = Impact produced / Time invested&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Leverage is the ROI for the effort put in.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Meta-skills&lt;/strong&gt; are important to know where to focus one’s time and energy to translate more of one’s efforts into impact.&lt;/li&gt;
&lt;li&gt;Leverage your time by always finding ways to perform activities quicker and making sure those activities will have a &lt;strong&gt;meaningful impact&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="optimize-for-learning"&gt;Optimize for learning&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Make your learning rate a priority&lt;/strong&gt;: it compounds like interest over time.&lt;/li&gt;
&lt;li&gt;Study code for core abstractions written by the best engineers at your company.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Write more code&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Go through any technical, educational material available internally.&lt;/li&gt;
&lt;li&gt;Master the programming languages that you use.&lt;/li&gt;
&lt;li&gt;Send your code reviews to the harshest critics.&lt;/li&gt;
&lt;li&gt;Enroll in classes on areas where you want to improve.&lt;/li&gt;
&lt;li&gt;Participate in design discussions of projects you’re interested in.&lt;/li&gt;
&lt;li&gt;Work on a diversity of projects.&lt;/li&gt;
&lt;li&gt;Make sure you’re on a team with at least a few senior engineers whom you can learn from.&lt;/li&gt;
&lt;li&gt;Jump fearlessly into code you don’t know.&lt;/li&gt;
&lt;li&gt;Learn new programming languages and frameworks.&lt;/li&gt;
&lt;li&gt;Invest in skills that are in high demand.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Read books&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Join a discussion group.&lt;/li&gt;
&lt;li&gt;Attend talks, conferences, and meetups.&lt;/li&gt;
&lt;li&gt;Build and maintain a strong network of relationships.&lt;/li&gt;
&lt;li&gt;Follow bloggers who teach.&lt;/li&gt;
&lt;li&gt;Write to teach.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tinker on side projects&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pursue what you love&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="prioritize-regularly"&gt;Prioritize regularly&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Track to-dos in a single list.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Focus on what produces value directly&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Focus on the &lt;em&gt;important and non-urgent&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Limit the amount of work in progress.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use implementation intentions&lt;/strong&gt; (if-then planning).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prioritize&lt;/strong&gt; routinely.&lt;/li&gt;
&lt;li&gt;Write down and &lt;em&gt;review&lt;/em&gt; to-dos.&lt;/li&gt;
&lt;li&gt;Reduce &lt;em&gt;context switches&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="part-2-execute-execute-execute"&gt;Part 2: Execute, Execute, Execute&lt;/h2&gt;
&lt;h3 id="invest-in-iteration-speed"&gt;Invest in iteration speed&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Move fast to learn fast.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Invest in time-saving tools&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Shorten your debugging and validation loops.&lt;/li&gt;
&lt;li&gt;Master your programming environment.&lt;/li&gt;
&lt;li&gt;Get proficient with your favorite text editor or IDE.&lt;/li&gt;
&lt;li&gt;Learn at least one productive, high-level programming language (&lt;em&gt;scripting&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;Get familiar with UNIX (or Windows) &lt;em&gt;shell commands&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Prefer the keyboard&lt;/em&gt; over the mouse.&lt;/li&gt;
&lt;li&gt;Automate your manual workflows.&lt;/li&gt;
&lt;li&gt;Test out ideas on an interactive interpreter.&lt;/li&gt;
&lt;li&gt;Make it fast and easy to run just the unit tests associated with your current changes.&lt;/li&gt;
&lt;li&gt;Don’t ignore non-engineering bottlenecks.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="measure-what-you-want-to-improve"&gt;Measure what you want to improve&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Use metrics to drive progress.&lt;/li&gt;
&lt;li&gt;Pick the right metric to incentivize the behavior you want.&lt;/li&gt;
&lt;li&gt;Instrument everything to understand what is going on.&lt;/li&gt;
&lt;li&gt;Internalize useful numbers (e.g., number of active users, requests per second, amount of data accessed and written daily, etc.).&lt;/li&gt;
&lt;li&gt;Be skeptical about data integrity.&lt;/li&gt;
&lt;li&gt;Log data liberally, in case it turns out to be useful later on.&lt;/li&gt;
&lt;li&gt;Build tools to iterate on data accuracy sooner.&lt;/li&gt;
&lt;li&gt;Write end-to-end integration tests to validate your entire analytics pipeline.&lt;/li&gt;
&lt;li&gt;Examine collected data sooner.&lt;/li&gt;
&lt;li&gt;Cross-validate data accuracy by computing the same metric in multiple ways.&lt;/li&gt;
&lt;li&gt;When a number does look off, dig into it early.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="validate-your-ideas-early-and-often"&gt;Validate your ideas early and often&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Find low-effort ways to validate your work.
&lt;ul&gt;
&lt;li&gt;Approach a problem iteratively to reduce wasted effort.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Continuously validate product changes with A/B testing.
&lt;ul&gt;
&lt;li&gt;Reduce the risk of large implementations by using small validations.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Beware the one-person team (you need feedback early to make sure you’re working on the right thing!).&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Be open and receptive to feedback&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Commit code early and often&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Request code reviews from thorough critics.&lt;/li&gt;
&lt;li&gt;Ask to bounce ideas off your teammates.&lt;/li&gt;
&lt;li&gt;Design the interface or API of a new system first.&lt;/li&gt;
&lt;li&gt;Send out a design document before devoting your energy to your code.&lt;/li&gt;
&lt;li&gt;If possible, structure ongoing projects so that there is some shared context with your teammates.&lt;/li&gt;
&lt;li&gt;Solicit buy-in for controversial features before investing too much time.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Build feedback loops&lt;/em&gt; for your decisions.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="improve-your-project-estimation-skills"&gt;Improve your project estimation skills&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Project estimation is one of the hardest skills that an effective engineer needs to learn. &lt;em&gt;But it’s crucial to master&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;To produce accurate estimates:
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Decompose the project&lt;/em&gt; into granular tasks.&lt;/li&gt;
&lt;li&gt;Estimate based on how long tasks will take, not on how long you or someone else wants them to take.&lt;/li&gt;
&lt;li&gt;Think of estimates as &lt;em&gt;probability distributions&lt;/em&gt;, not best-case scenarios.&lt;/li&gt;
&lt;li&gt;Let the person doing the actual task make the estimate.&lt;/li&gt;
&lt;li&gt;Beware of anchoring bias (e.g., hearing about a low estimate from someone else may skew our own estimate later to be too low).&lt;/li&gt;
&lt;li&gt;Use multiple approaches to estimate the same task (e.g., estimate from past experiences, decompose a larger task into smaller ones and estimate each one).&lt;/li&gt;
&lt;li&gt;Beware the mythical man-month. Having more people on a project doesn’t necessarily mean it will be completed faster. Communication overhead, context switching, and other factors can slow down the team as much as $O(n^2)$ considering the number of people involved.&lt;/li&gt;
&lt;li&gt;Validate estimates against historical data.&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;time-boxing&lt;/strong&gt; to constrain tasks that can grow in scope.&lt;/li&gt;
&lt;li&gt;Allow others to challenge estimates.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Allow buffer room for the unknown in the schedule.&lt;/li&gt;
&lt;li&gt;Define measurable milestones.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Do the riskiest tasks first&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Know the limits of overtime.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="part-3-build-long-term-value"&gt;Part 3: Build Long-Term Value&lt;/h2&gt;
&lt;h3 id="balance-quality-with-pragmatism"&gt;Balance Quality with Pragmatism&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Establish a culture of reviewing code.
&lt;ul&gt;
&lt;li&gt;Catch bugs or design shortcomings early.&lt;/li&gt;
&lt;li&gt;Increase accountability for code changes.&lt;/li&gt;
&lt;li&gt;Provide an avenue for sharing best practices.&lt;/li&gt;
&lt;li&gt;Increase long-term agility.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Invest in good software abstractions to simplify difficult problems.
&lt;ul&gt;
&lt;li&gt;Reduce the complexity of the original problem into easier-to-understand primitives.&lt;/li&gt;
&lt;li&gt;Reduce future application maintenance and make it easier to apply future improvements.&lt;/li&gt;
&lt;li&gt;DRY principle: solve the hard problems once and re-use the solutions multiple times.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Scale code quality with &lt;em&gt;automated testing&lt;/em&gt;.
&lt;ul&gt;
&lt;li&gt;Make large refactors with confidence.&lt;/li&gt;
&lt;li&gt;Offer executable documentation.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Don&amp;rsquo;t test everything&lt;/em&gt;: focus on the most important parts of the code and make sure everything critical is covered.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Manage your technical debt.
&lt;ul&gt;
&lt;li&gt;Pay it periodically. Incur it when necessary to meet deadlines.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Repay the debts with the highest interest rates first&lt;/em&gt; (i.e., focus on what produces the most leverage).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="minimize-operational-burden"&gt;Minimize Operational Burden&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Embrace operational simplicity.
&lt;ul&gt;
&lt;li&gt;Increased complexity introduces more potential single points of failure.&lt;/li&gt;
&lt;li&gt;New engineers face a steeper learning curve when learning and understanding the new systems.&lt;/li&gt;
&lt;li&gt;Effort towards improving abstractions, libraries, and tools gets diluted across the different systems.&lt;/li&gt;
&lt;li&gt;Do the simple thing first.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Build systems to fail fast&lt;/strong&gt;.
&lt;ul&gt;
&lt;li&gt;Pinpoint the source of errors.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Make debugging easier&lt;/em&gt; by not masking your errors and by not deferring failures until later.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Relentlessly automate&lt;/strong&gt;.
&lt;ul&gt;
&lt;li&gt;Don&amp;rsquo;t underestimate the future frequency of the task.&lt;/li&gt;
&lt;li&gt;Internalize the time savings over a long time horizon.&lt;/li&gt;
&lt;li&gt;Automate mechanics over decision-making.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Make batch processes idempotent&lt;/strong&gt;.
&lt;ul&gt;
&lt;li&gt;At least, make processes &lt;em&gt;&amp;ldquo;retryable&amp;rdquo;&lt;/em&gt; if they cannot be made idempotent.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Hone your ability to respond and recover quickly.
&lt;ul&gt;
&lt;li&gt;Plan and practice failure modes.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="invest-in-your-teams-growth"&gt;Invest in Your Team’s Growth&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Make hiring everyone’s responsibility.
&lt;ul&gt;
&lt;li&gt;Identify which qualities you care about the most in your colleagues: &lt;em&gt;keep the bar high&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Make sure the recruiting process is effective.&lt;/li&gt;
&lt;li&gt;Adapt interview problems to different levels of difficulty based on the candidate&amp;rsquo;s experience.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Design a good onboarding process.
&lt;ul&gt;
&lt;li&gt;Ramp up new engineers as quickly as possible (e.g., with &lt;em&gt;codelabs&lt;/em&gt;).
&lt;ul&gt;
&lt;li&gt;Help the people around you be successful.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Impart the team’s culture and values (e.g., have &lt;em&gt;onboarding talks&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;Expose new engineers to the breadth of fundamentals needed to succeed (e.g., with &lt;em&gt;mentorship&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;Socially integrate new engineers onto the team (e.g., give them starter tasks to feel they&amp;rsquo;re part of the team faster).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Share ownership of code (increase the &lt;em&gt;bus factor&lt;/em&gt;).
&lt;ul&gt;
&lt;li&gt;Avoid one-person teams.&lt;/li&gt;
&lt;li&gt;Review each other’s code and software designs.&lt;/li&gt;
&lt;li&gt;Make sure the team is exposed to different types of tasks and responsibilities regularly.&lt;/li&gt;
&lt;li&gt;Focus on readable and high-quality code.&lt;/li&gt;
&lt;li&gt;Share software decisions and architecture clearly.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Make sure code and workflows are documented properly&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Invest in teaching and mentoring&lt;/em&gt;.
&lt;ul&gt;
&lt;li&gt;The more effective the team becomes, the more freedom there is to work on new projects.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Build collective wisdom with post-mortems (e.g., at NASA, these become the user manual).&lt;/li&gt;
&lt;li&gt;Build a great engineering culture.
&lt;ul&gt;
&lt;li&gt;Optimize for iteration speed.&lt;/li&gt;
&lt;li&gt;Always automate.&lt;/li&gt;
&lt;li&gt;Use the right software abstractions.&lt;/li&gt;
&lt;li&gt;Nurture a respectful working environment.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Allot experimentation time&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Foster a culture of learning&lt;/em&gt; (CI/CD: &lt;em&gt;continuous improvement, continuous delightfulness&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hire the best&lt;/strong&gt;!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Edmond opened my eyes to the importance of being an effective engineer, showing what that entails and how to concretely achieve it. His extraordinary technical journey and knowledge of the field are evident throughout the book, and I found myself nodding in agreement with many of his points. He made me think about how I could apply his advice to my own work. Notably, the key concept of &lt;strong&gt;leverage&lt;/strong&gt; resonated deeply with me and ended up being the cornerstone of &lt;a href="https://www.sglavoie.com/posts/building-task-planner-react-native/"&gt;the final project I built for my bachelor&amp;rsquo;s degree&lt;/a&gt;: &lt;em&gt;ProductiviDo - An efficient task planner focusing on high-leverage activities&lt;/em&gt;.&lt;/p&gt;
&lt;h2 id="resources-and-references"&gt;Resources and references&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://edmondlau.co/"&gt;Edmond Lau&lt;/a&gt; - The author&amp;rsquo;s personal website.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.sglavoie.com/posts/building-task-planner-react-native/"&gt;ProductiviDo&lt;/a&gt; - A simple and efficient todo-app built with React-Native.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.goodreads.com/book/show/25238425-the-effective-engineer"&gt;The Effective Engineer: How to Leverage Your Efforts In Software Engineering to Make a Disproportionate and Meaningful Impact&lt;/a&gt; - goodreads.com.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.effectiveengineer.com/"&gt;The Effective Engineer&lt;/a&gt; - by Edmond Lau.&lt;/li&gt;
&lt;/ul&gt;</content:encoded><dc:creator>Sébastien Lavoie</dc:creator><pubDate>Sun, 16 Apr 2023 14:49:00 -0600</pubDate><guid isPermaLink="false">https://www.sglavoie.com/posts/book-summary-the-effective-engineer/</guid><category>learnings</category><category>advice</category><category>best practices</category><category>books</category><category>career</category><category>skimming-notes</category></item><item><title>Book summary: Letters to a New Developer</title><link>https://www.sglavoie.com/posts/book-summary-letters-to-a-new-developer/</link><description>If you are still early in your career as a software developer (or not so much!), I think you might enjoy reading Letters to a New Developer: What I Wish I Had Known When Starting My Development Career written by Dan Moore, who also features a very insightful blog.</description><content:encoded>&lt;hr&gt;
&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve taken quite a few notes while devouring that book, which is a quick and easy read. It&amp;rsquo;s not the typical non-fiction, technically-oriented manual: this book makes you feel like having an older family member taking the time to sit right next to you to openly share all sorts of golden nuggets from a lifetime of rich and varied experiences so you can get prepared to face the challenges that lie ahead in your own career and avoid some of the more common mistakes during the journey. It is the kind of publication you can read literally five minutes at a time thanks to the convenient format it adopts.&lt;/p&gt;
&lt;p&gt;Some of the following notes are verbatim and reading the whole title will be worth it! Nevertheless, you will find below some passages that deeply resonated with me, reflecting the gist of this prose from my perspective. Beware! There are numerous gems to be gleaned from this excellent author.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="book-summary"&gt;Book summary&lt;/h2&gt;
&lt;h2 id="first-month-at-a-job"&gt;First month at a job&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;See problems as opportunities to contribute.&lt;/li&gt;
&lt;li&gt;During the &lt;strong&gt;onboarding&lt;/strong&gt;, figure out:
&lt;ul&gt;
&lt;li&gt;All the &lt;strong&gt;HR stuff&lt;/strong&gt;: benefits, agreements, bonuses, interacting with different departments, meetings, requesting vacation, raises/reviews cycles.&lt;/li&gt;
&lt;li&gt;And the &lt;strong&gt;technical stuff&lt;/strong&gt; too: who to ask questions to, how to ask them (batch them, chat, meeting, etc.), how long to work on a problem before asking for help, how to communicate progress, how to set up a local development environment, CI/CD and branches process, when do you know you&amp;rsquo;re done working on a task, how are tasks managed (manager, issue tracker, etc.).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Questions that arise and have no answers → See where to document them (e.g. wiki).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;First impressions&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;Be there early.&lt;/li&gt;
&lt;li&gt;Say what you&amp;rsquo;ll do, then do it.&lt;/li&gt;
&lt;li&gt;Research before asking questions (and record answers).&lt;/li&gt;
&lt;li&gt;Volunteer to take extra work (don&amp;rsquo;t become a punching bag, though).&lt;/li&gt;
&lt;li&gt;Own your mistakes but don&amp;rsquo;t make the same ones twice.&lt;/li&gt;
&lt;li&gt;Be polite and professional, always.&lt;/li&gt;
&lt;li&gt;Make sure with manager we&amp;rsquo;re on the same page, working on the right stuff, at the right cadence with appropriate updates.&lt;/li&gt;
&lt;li&gt;Write docs to make the next hire easier.&lt;/li&gt;
&lt;li&gt;Have the reputation to be a hard, smart worker: it will follow you.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Be ready for the trepidations: &lt;strong&gt;celebrate successes&lt;/strong&gt; (&amp;quot;&lt;em&gt;today I [fixed, learnt&amp;hellip;]&lt;/em&gt;&amp;quot;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;To excel&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;Communicate what you&amp;rsquo;re working on.&lt;/li&gt;
&lt;li&gt;Ask questions.&lt;/li&gt;
&lt;li&gt;Don&amp;rsquo;t make the same mistake twice: write down what went wrong and plan to avoid repeating them.&lt;/li&gt;
&lt;li&gt;Show up consistently.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Know the team&lt;/strong&gt;: their names, their roles, their behaviours (who posts what, who is in which meetings, who seems funny and approachable on Slack, etc.).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Read code and take notes&lt;/strong&gt;: dig into a section of the system, follow data flow, make diagrams of how things are connected.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="questions"&gt;Questions&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Ask prepared questions&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;Research before asking.&lt;/li&gt;
&lt;li&gt;Find where to search (Slack, issue trackers, YT, internal docs or wiki, etc.).&lt;/li&gt;
&lt;li&gt;But also be mindful of how long you should spend time searching (Is there a tight deadline? Are you wasting your time?).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ask good questions&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;Specify the problem in detail, narrow the scope as much as possible.&lt;/li&gt;
&lt;li&gt;Show you&amp;rsquo;ve done &lt;em&gt;research&lt;/em&gt;. Links, videos, posts, logs (without sensitive info), etc.&lt;/li&gt;
&lt;li&gt;Follow up after a day or so to share additional research.&lt;/li&gt;
&lt;li&gt;Express gratitude.&lt;/li&gt;
&lt;li&gt;If you have the answer, add it.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Don&amp;rsquo;t be afraid to ask questions&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;If it&amp;rsquo;s a learning experience, spend more time figuring out the answer.&lt;/li&gt;
&lt;li&gt;The more time you have before the task is due, the more time you should spend looking for an answer.&lt;/li&gt;
&lt;li&gt;How busy is the rest of the team? If they can&amp;rsquo;t help, you&amp;rsquo;ll have to do it yourself.&lt;/li&gt;
&lt;li&gt;If there&amp;rsquo;s a bug that&amp;rsquo;s really specific to the internal project, asking for help from coworkers is probably best (be careful not to disclose business knowledge!).&lt;/li&gt;
&lt;li&gt;Have you tried working on other aspects of the task? It may unblock you.&lt;/li&gt;
&lt;li&gt;Put in the effort before asking: research, list hypotheses, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ask why&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;It may help prevent mistakes down the line (e.g. wrong choice of tech) and get more perspective, understand better.&lt;/li&gt;
&lt;li&gt;Document findings in wiki or similar (could be in a question/answer format).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;If you don&amp;rsquo;t know something&lt;/strong&gt;, don&amp;rsquo;t guess or make an incorrect decision: admit it and say you&amp;rsquo;ll find out the answer (may have to ask others in the process too).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="writing"&gt;Writing&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Read your texts out aloud&lt;/strong&gt;: spot typos, awkward sentences, etc.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Document the intent behind what you&amp;rsquo;re doing&lt;/strong&gt; (code, reason for change, who asked what&amp;hellip;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Emails&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;As &lt;em&gt;short&lt;/em&gt; as possible. Otherwise, add &lt;em&gt;executive summary&lt;/em&gt; at the top.&lt;/li&gt;
&lt;li&gt;Is it sensitive? Maybe have face-to-face instead.&lt;/li&gt;
&lt;li&gt;Add &lt;em&gt;links&lt;/em&gt; to supporting documents rather than attaching them. Email chains are hard to follow: may put them in a document instead.&lt;/li&gt;
&lt;li&gt;Don&amp;rsquo;t use &lt;em&gt;relative time references&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Keep them &lt;em&gt;focused&lt;/em&gt;: go into &lt;em&gt;one topic&lt;/em&gt;. New topic = new email with different subject line.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Real-time messaging: Default to &lt;em&gt;public&lt;/em&gt; channels to benefit the organization.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Write a technical ebook&lt;/em&gt;: working on a complex project over time and being able to see the high-level and details, all presented in a coherent way for the readers.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Write and update technical documentation&lt;/strong&gt;: you save time in the long run, it&amp;rsquo;s useful for you and the rest of the organization.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Blog&lt;/strong&gt;: this is the process of clarifying your own thoughts. You&amp;rsquo;ll be a better writer and thinker for it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Motivation about writing&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;It crystallizes thoughts, make them clearer;&lt;/li&gt;
&lt;li&gt;Builds credibility;&lt;/li&gt;
&lt;li&gt;Helps others;&lt;/li&gt;
&lt;li&gt;Illustrates an ability to convey technical information and context.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="tools-to-learn"&gt;Tools to learn&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Leverage for increased productivity&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Test suite&lt;/em&gt;: living documentation. Can evolve code base without fear.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Libraries&lt;/em&gt; and &lt;em&gt;frameworks&lt;/em&gt;: saves time.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;IaaS&lt;/em&gt; (infrastructure as a service, e.g. AWS EC2): can use APIs to manage.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Paas&lt;/em&gt; (platform as a service, e.g. Heroku): Allows to focus on business logic.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Saas&lt;/em&gt; (software as a service, e.g. Google Apps): integrate with existing software.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Command-line&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Typing is quicker&lt;/em&gt; than using GUIs for many tasks.&lt;/li&gt;
&lt;li&gt;Can automate &lt;em&gt;recurring tasks&lt;/em&gt; easily.&lt;/li&gt;
&lt;li&gt;Can easily &lt;em&gt;share task scripts&lt;/em&gt; with others.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;jq, awk, sed&lt;/em&gt;: put them to good use.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Version control&lt;/strong&gt;: if in doubt, use it, except for large files and other scenarios that don&amp;rsquo;t make sense.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Text editor&lt;/strong&gt;: learn one well.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;IDEs&lt;/strong&gt;: Use them when it makes sense (programming in Java with a text editor? Probably a bad idea).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Standard library&lt;/strong&gt;: get a good overview of what&amp;rsquo;s available, leads to transferable skills, more idiomatic code, better tested, etc.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Automated testing&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;Prevents bug regression.&lt;/li&gt;
&lt;li&gt;Serves as live documentation.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Network engineering&lt;/strong&gt;: Learn about it, it will pay off. Know:
&lt;ul&gt;
&lt;li&gt;Basics of routing;&lt;/li&gt;
&lt;li&gt;Basics of DNS;&lt;/li&gt;
&lt;li&gt;Rundown of the OSI model;&lt;/li&gt;
&lt;li&gt;TCP/IP, HTTP, what a proxy is;&lt;/li&gt;
&lt;li&gt;Answer questions like How do CDNs work, what&amp;rsquo;s the difference between HTTP and WebSockets, how does SSL work, what can nginx be used for&amp;hellip;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SQL&lt;/strong&gt;: this is fundamental knowledge as it&amp;rsquo;s almost everywhere.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Debuggers&lt;/strong&gt;: learn how to debug in your IDE, on the command-line and in a web browser (your IDE won&amp;rsquo;t always be available).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Benchmarking&lt;/strong&gt;: do not optimize prematurely and use benchmarking tools when performance matters to see if the code is fast enough.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Search engines&lt;/strong&gt;: learn to be an expert Googler.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="practices"&gt;Practices&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Solve problems, don&amp;rsquo;t just write code&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;Use library/framework.&lt;/li&gt;
&lt;li&gt;Use third-party SaaS tool.&lt;/li&gt;
&lt;li&gt;Make sure tasks need to be done. (Why are you doing it? Does it provide value?)&lt;/li&gt;
&lt;li&gt;If a task isn&amp;rsquo;t recurring often enough, manual work may be the best way to go (time to automate vs. actual savings).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Think ahead, envision all paths (not just the happy one) before taking a decision.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Read code&lt;/strong&gt;: scan it; dive down; use the &lt;em&gt;scientific method&lt;/em&gt; to make changes and debug.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Get good at estimating your work&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Opportunity cost&lt;/em&gt; (can&amp;rsquo;t do everything: prioritize and do the tasks that &lt;em&gt;bring the most value&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Scheduling&lt;/em&gt;: software is not built in a vacuum, hard and soft deadlines will occur.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Discussing requirements&lt;/em&gt; first can save a lot of troubles and money: building the wrong thing quickly is of no use. Use lightweight prototyping tools instead of building the whole software.&lt;/li&gt;
&lt;li&gt;Recommended reading: &lt;a href="https://www.goodreads.com/book/show/93891.Software_Estimation"&gt;Software Estimation: Demystifying the Black Art&lt;/a&gt;, by Steve McConnell.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here&amp;rsquo;s one way to keep track of your estimates in a spreadsheet:&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Task&lt;/th&gt;
 &lt;th&gt;Low estimate&lt;/th&gt;
 &lt;th&gt;High estimate&lt;/th&gt;
 &lt;th&gt;Notes, questions, research&lt;/th&gt;
 &lt;th&gt;Final estimate&lt;/th&gt;
 &lt;th&gt;Estimate in days&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;Requirements definition, research, development, testing, deployment, estimates on bug fixes&amp;hellip;&lt;/td&gt;
 &lt;td&gt;Everything going smoothly.&lt;/td&gt;
 &lt;td&gt;Facing obstacles, having to rebuild part of the system, etc.&lt;/td&gt;
 &lt;td&gt;Answer questions and verify assumptions to complete the estimate.&lt;/td&gt;
 &lt;td&gt;(low + high) * 1.2 (add 20%, &amp;ldquo;fudge factor&amp;rdquo;)&lt;/td&gt;
 &lt;td&gt;Total hours estimated divided by number of ideal hours per day&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Tracking the actual accuracy of tasks&lt;/em&gt; can be insightful too.&lt;/li&gt;
&lt;li&gt;Always tell people who are depending on the completion of a task &lt;em&gt;if it&amp;rsquo;s going to take longer than expected&lt;/em&gt;. Share alternative solutions if you have any.&lt;/li&gt;
&lt;li&gt;Even for side projects or when working on open source projects, it may be useful to &lt;em&gt;practice estimating&lt;/em&gt; (and users like seeing a roadmap).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Debug systems&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;Make the problem as &lt;em&gt;simple&lt;/em&gt; as possible.&lt;/li&gt;
&lt;li&gt;Begin with an &lt;em&gt;hypothesis&lt;/em&gt; and either prove it or refine it.&lt;/li&gt;
&lt;li&gt;Determine the &lt;em&gt;desired end state&lt;/em&gt;: fix the root problem but if it&amp;rsquo;s too costly, find a workaround if possible.&lt;/li&gt;
&lt;li&gt;Pay &lt;em&gt;attention&lt;/em&gt; if anything seems amiss.&lt;/li&gt;
&lt;li&gt;Keep &lt;em&gt;notes&lt;/em&gt; about what you&amp;rsquo;ve tried.&lt;/li&gt;
&lt;li&gt;If there&amp;rsquo;s a new bug, &lt;em&gt;inspect recent changes&lt;/em&gt; in the log.&lt;/li&gt;
&lt;li&gt;Write an &lt;em&gt;automated test&lt;/em&gt; before fixing the bug so it doesn&amp;rsquo;t reappear and you&amp;rsquo;ll be sure when the bug was fixed.&lt;/li&gt;
&lt;li&gt;Follow the &lt;em&gt;flow of data&lt;/em&gt; (e.g. in a three-tier application, start with the browser or with the database).&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Minimize impact&lt;/em&gt; for users if the bug is in the production environment. Ideally, test on the &lt;em&gt;staging&lt;/em&gt; environment.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Test the right thing&lt;/em&gt;. Make sure that what&amp;rsquo;s being tested mirrors as closely as possible where the bug appears.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Assume positive intent&lt;/strong&gt;: be solution-focused.
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;ROI on trust&lt;/em&gt;: about 4% of the population are sociopaths; meaning 96% of the population has some working conscience and could be trusted by default to reap great benefits. This may speed decision making, for instance.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Express gratitude&lt;/strong&gt;: it will make you feel better and showing appreciation to others will make working with colleagues a breeze. Thanking people and writing a &lt;em&gt;gratitude journal&lt;/em&gt; will be helpful.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cultivate the skill of undivided attention&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;To produce your best output, you need to &lt;em&gt;commit to deep work&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;To thrive in today&amp;rsquo;s economy, you need to &lt;em&gt;be able to quickly master hard things&lt;/em&gt; and be able to &lt;em&gt;produce at an elite level&lt;/em&gt; in terms of both &lt;em&gt;quality&lt;/em&gt; and &lt;em&gt;speed&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;To learn hard things quickly, you must &lt;em&gt;focus intensely without distraction&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Add routines and rituals to your working life&lt;/em&gt; to limit the amount of willpower required to get started.&lt;/li&gt;
&lt;li&gt;Book recommendation: &lt;a href="https://www.calnewport.com/books/deep-work/"&gt;Deep Work: Rules for Focused Success in a Distracted World&lt;/a&gt;, by Cal Newport.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Build empathy&lt;/strong&gt;: Remember your own frustrations. Your users are people who can struggle on tasks you&amp;rsquo;d find simple yourself. They&amp;rsquo;re trying to make something work, just like you.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Don&amp;rsquo;t complain about the code&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;It&amp;rsquo;s not helpful.&lt;/li&gt;
&lt;li&gt;It displays a lack of empathy.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Avoid jargon&lt;/strong&gt;: If you can&amp;rsquo;t explain it to a non-technical user, you don&amp;rsquo;t understand it well enough (good framework: try the &lt;a href="https://en.wikipedia.org/wiki/Feynman_Technique"&gt;Feynman Technique&lt;/a&gt;). You gain clarity for yourself, the ability to teach others and you can influence your organization. (Personal additional: get good at critical thinking and use &lt;a href="https://untools.co/"&gt;frameworks for better thinking&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Time is money&lt;/strong&gt;: &lt;em&gt;buying services from others gives you time&lt;/em&gt;.
&lt;ul&gt;
&lt;li&gt;Buying a book or video instead of reading free documentation.&lt;/li&gt;
&lt;li&gt;Buying and using exceptional tools (e.g. JetBrains IDEs).&lt;/li&gt;
&lt;li&gt;Paying for support.&lt;/li&gt;
&lt;li&gt;Buy commercial software.&lt;/li&gt;
&lt;li&gt;Pay for consulting or training.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Say no&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;If there are pending tasks, ensure they are worked in the &lt;em&gt;right order of priority&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Life is short&lt;/em&gt;: if you end up working 90 hours per week, make sure you&amp;rsquo;re happy doing it and are not sacrificing other important aspects.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Build on your own&lt;/strong&gt;: pick a project you can envision yourself sticking to for more than six month and learn.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Consistency is key&lt;/strong&gt;: learn by showing up every day. Becoming great at something takes time.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="understanding-the-business"&gt;Understanding the business&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Software is about people, not code&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;Software is created for people.&lt;/li&gt;
&lt;li&gt;Users need to be heard to buy in.&lt;/li&gt;
&lt;li&gt;Most people don&amp;rsquo;t care about the code. &lt;em&gt;Their goal is to get things done&lt;/em&gt;. Beautiful code that doesn&amp;rsquo;t solve the right problem is useless.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Outcomes over output&lt;/strong&gt;: the end-goal for the business is more &lt;em&gt;revenue&lt;/em&gt;, more &lt;em&gt;profit&lt;/em&gt;, more &lt;em&gt;users&lt;/em&gt;, more &lt;em&gt;product availability&lt;/em&gt;, happier users, etc. Your contributions should be holistic in nature and work towards achieving these goals.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Understanding the big picture&lt;/em&gt; of why money is spent on certain projects or services pays off as you can better contribute to the bottom line of the company by knowing why things are done the way they are.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Business model&lt;/strong&gt;: know how money is being made. Get a good understanding of the domain in which the business operates.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Knowing how software is used at the company&lt;/em&gt; helps you to understand the business.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;The size of a company impacts how it solves problems&lt;/em&gt;: a bigger company will usually move more slowly towards its goals when change is required, attacking possibly bigger problems with powerful tools and teams. A smaller company may pivot more quickly and shift focus, but it may not work on problems of comparative scales.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Starting a company&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;As a new developer, starting one wouldn&amp;rsquo;t be wise. Learning to become a software developer and learning how to run a business all at once can lead to a huge amount of stress.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;It will take longer than you think&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Know your &lt;em&gt;financial runway&lt;/em&gt; (&amp;ldquo;burn rate&amp;rdquo; vs. what you have in the bank). Extend it by lowering the burn rate.&lt;/li&gt;
&lt;li&gt;Consider your &lt;em&gt;emotional runway&lt;/em&gt;: how are things going for you outside of work? Are there any trying events like moving or having a new baby?&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Talk to your customers&lt;/em&gt;: learn from them. Get feedback.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Provide value to customers&lt;/em&gt;: you won&amp;rsquo;t have time to make everything go as smoothly as you&amp;rsquo;d like, but the customer must still be served.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Know your market&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Be ready to move away from code and focus more on a position of &lt;em&gt;management&lt;/em&gt; as the company grows.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Learn from your customers&lt;/em&gt;:
&lt;ul&gt;
&lt;li&gt;Digging into a ticketing system will be informative to understand how a product is being used and may reveal flaws or bugs.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Focus on the problems mentioned, not on the solutions proposed&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Ask them about their pressing problems, not only those that have been reported so far. This may inform about issues with related systems.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="learning"&gt;Learning&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Never stop learning&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;Be clear about &lt;em&gt;why&lt;/em&gt; you want to be learning.&lt;/li&gt;
&lt;li&gt;Once you have the why, determine the &lt;em&gt;what&lt;/em&gt; that will take you there.&lt;/li&gt;
&lt;li&gt;Once you have both of the above, find the &lt;em&gt;how&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Execute.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Build expert intuition&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;It&amp;rsquo;s the difference between a junior and a senior developer.&lt;/li&gt;
&lt;li&gt;A regular world + many opportunities to learn + frequent feedback + expert intuition.&lt;/li&gt;
&lt;li&gt;Regular world: gives a chance to find out whether you&amp;rsquo;d prefer to specialize in a specific branch of the software development tree or remain a generalist.&lt;/li&gt;
&lt;li&gt;Many opportunities to learn: write code, work on technical projects and observe those who are more senior than you.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Frequent feedback&lt;/em&gt;: code reviews and one on ones with the manager. Reflect on your performance with a daily &lt;em&gt;journal&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Know what to learn&lt;/strong&gt; (i.e. general skills vs. specific technology and techniques):
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Domain knowledge&lt;/em&gt;: understand the business you are in, who the major players are, etc. If you stick in a given domain long enough, you become more valuable as this kind of knowledge tends to last a long time. Talk to experts and read books.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Theoretical expertise&lt;/em&gt;: data structures and algorithms, HTTP and best practices fall within this category. It serves for years as a solid foundation for everything else. Books are a fine source to delve deeper.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Practical knowledge&lt;/em&gt;:
&lt;ul&gt;
&lt;li&gt;React, Kubernetes, Rails are some examples of specific technologies that belong in this category.&lt;/li&gt;
&lt;li&gt;Have a good understanding of the underlying technology whenever possible (e.g. learn the language in depth, not just the framework).&lt;/li&gt;
&lt;li&gt;This type of knowledge &lt;em&gt;tends to age quickly&lt;/em&gt; and can be learnt through &lt;em&gt;videos&lt;/em&gt;, &lt;em&gt;conference talks&lt;/em&gt; and &lt;em&gt;tutorials&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Leadership knowledge&lt;/em&gt;: This will pay dividends through your career. Books and experience in the real-world are useful here.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Avoid being an expert beginner&lt;/strong&gt; (an authority with nontransferable skills):
&lt;ul&gt;
&lt;li&gt;Never believe you have all the answers.&lt;/li&gt;
&lt;li&gt;Don&amp;rsquo;t bend tools to do something they weren&amp;rsquo;t meant to do.&lt;/li&gt;
&lt;li&gt;Don&amp;rsquo;t ignore best practices (but don&amp;rsquo;t blindly apply them everywhere either!).&lt;/li&gt;
&lt;li&gt;Keep in touch with the larger software community: you may temporarily be at the top somewhere technically speaking, but that won&amp;rsquo;t remain true in a bigger context.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Pair with people that are more experienced than you&lt;/em&gt;: ask them questions, read the pull requests they submit.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pattern match to be a just-in-time learner&lt;/strong&gt;: explore by pattern and analogy (e.g. compare terminology that&amp;rsquo;s similar to tools you&amp;rsquo;ve used before) and learn just enough to get the task done. Learn the nuances as you go.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Learning boring stuff&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;Focus on the big picture. &lt;em&gt;Why&lt;/em&gt; are you learning this?&lt;/li&gt;
&lt;li&gt;Notice the &lt;em&gt;fun&lt;/em&gt; parts.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Take breaks&lt;/em&gt; when needed. If no strict deadline is in sight, you might cross off a different task on your to-do list for now.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Automate&lt;/em&gt; what you can but consider clearly the time savings when doing so.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Learn relevant things&lt;/em&gt;: this applies once you have a base to lean on, but accumulating random concepts that aren&amp;rsquo;t often applicable after that isn&amp;rsquo;t useful (unused knowledge rots and gets forgotten).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Your team will teach you&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;They can teach you more than you can learn on your own: tools; languages; frameworks; business domain knowledge; approaches to problem-solving; understanding of the problem; stakeholder empathy.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Observe how senior people work&lt;/em&gt; (face-to-face, read their code and pull requests).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use an RSS reader&lt;/strong&gt;: for blogs, online community discussions, tags in Stack Overflow, news sites.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Listen to podcasts&lt;/strong&gt;: good to gather ideas about high-level concepts while doing other things (dishes, exercise, watering plants, cooking, etc.).
&lt;ul&gt;
&lt;li&gt;Listen to those that are &lt;em&gt;domain specific&lt;/em&gt; to help you at work.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Technology specific&lt;/em&gt;: expose yourself to tools, techniques and libraries.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;General software development&lt;/em&gt;: those are broadly applicable to software engineering and will work across different jobs you have within the industry.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Subscribe to email newsletters&lt;/strong&gt;: great to get curated content on a given topic. These could include software development practices, security, AWS and career skills.
&lt;ul&gt;
&lt;li&gt;Find them with searches like &lt;code&gt;&amp;lt;subject area&amp;gt; weekly/email newsletter&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Read the archives&lt;/em&gt; first to get a sense of whether you&amp;rsquo;ll enjoy the content.&lt;/li&gt;
&lt;li&gt;Like with podcasts, focus on what&amp;rsquo;s interesting and &lt;em&gt;skim&lt;/em&gt; the rest.&lt;/li&gt;
&lt;li&gt;When sources lead to more articles of interest, those can be captured in your &lt;em&gt;RSS reader&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Good to &lt;em&gt;explore new technologies and frameworks&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;To start your own, &lt;a href="https://tinyletter.com/"&gt;TinyLetter&lt;/a&gt; is a great option.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Read great books about software development&lt;/strong&gt;: don&amp;rsquo;t look for cutting-edge information but rather for a source of timeless practices.
&lt;ul&gt;
&lt;li&gt;Good examples include &lt;a href="https://archive.org/details/mythicalmanmonth00broo"&gt;The Mythical Man-Month&lt;/a&gt;, &lt;a href="https://pragprog.com/titles/tpp20/the-pragmatic-programmer-20th-anniversary-edition/"&gt;The Pragmatic Programmer&lt;/a&gt;, &lt;a href="https://martinfowler.com/books/refactoring.html"&gt;Refactoring&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Ask great engineers&lt;/em&gt; you respect for recommendations.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Listen actively&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Do not multitask&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Take notes of&amp;hellip;&lt;/em&gt; salient points; ah-ha moments; terms to review in the future (those concepts you may not understand). Note the date of the conversation as well.&lt;/li&gt;
&lt;li&gt;If it is a video chat, see whether it can be &lt;em&gt;recorded&lt;/em&gt;. Turn on video if possible to get contextual clues.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Learn two programming languages&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;Lets you see the strengths and weaknesses of your first language.&lt;/li&gt;
&lt;li&gt;May support concepts that weren&amp;rsquo;t there before (e.g. classes in Java vs. their absence in Perl).&lt;/li&gt;
&lt;li&gt;Makes it easier to learn a third language.&lt;/li&gt;
&lt;li&gt;Illustrates &lt;em&gt;different approaches&lt;/em&gt; to common problems.&lt;/li&gt;
&lt;li&gt;Teaches you how languages fit certain problems better than others.&lt;/li&gt;
&lt;li&gt;Makes you less passionate about your first language. &lt;em&gt;Programming languages are only tools&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Makes it clear what you understand about language #1.&lt;/li&gt;
&lt;li&gt;Tutorials are great to get started and &lt;em&gt;side projects&lt;/em&gt; even better to cement the learning.&lt;/li&gt;
&lt;li&gt;Generally, &lt;em&gt;learn at least two of &amp;ldquo;everything&amp;rdquo;&lt;/em&gt; (e.g. databases, frameworks, development methodologies, etc.).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="mistakes"&gt;Mistakes&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Get used to failure&lt;/strong&gt;: learning something new is difficult. &lt;em&gt;Document internal knowledge&lt;/em&gt; as best as you can so the same mistakes do not repeat themselves. Look around (online, colleagues&amp;hellip;) to make sure the problem you are trying to solve hasn&amp;rsquo;t been worked on already and take any new information into account.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Making mistakes is okay&lt;/strong&gt;:
&lt;ol&gt;
&lt;li&gt;Find out what the &lt;em&gt;oversight&lt;/em&gt; was so you don&amp;rsquo;t repeat the same mistake.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Acknowledge&lt;/em&gt; you made an error.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Clean up&lt;/em&gt; the mess, with or without help.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Avoid making the same mistake again&lt;/em&gt;. You might keep notes around, write a blog post, etc. Document it or create a script to solve the issue from now on if applicable and share your new knowledge with the rest of the team.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mistakes are forgiven, hiding them is not&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;Make sure you did a mistake to start with.&lt;/li&gt;
&lt;li&gt;The people who need to know about your errors should be told. &lt;em&gt;Transparency and honesty are important&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Think of a plan to fix the mistake (both short-term and long-term).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Don&amp;rsquo;t make the same mistake twice&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;Make sure you understand what the mistake was.&lt;/li&gt;
&lt;li&gt;Dive deeper when it makes sense. For instance, it is worth mastering a version control system as this is a tool that&amp;rsquo;s going to be used all the time and is critical to understand when working with other software engineers.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Don&amp;rsquo;t be afraid to &amp;ldquo;fail&amp;rdquo;&lt;/strong&gt;: the only true failure is to quit working towards success.
&lt;ul&gt;
&lt;li&gt;Failures don&amp;rsquo;t stop happening when you become a &amp;ldquo;better&amp;rdquo; developer.&lt;/li&gt;
&lt;li&gt;The more you fail, the more you learn.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;You don&amp;rsquo;t know what you don&amp;rsquo;t know&lt;/strong&gt;. Doing pattern matching and recognizing concepts at a high level will help when there&amp;rsquo;s a need to dig deeper.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;When you see someone else making a mistake&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Make sure you have all the necessary context&lt;/em&gt; (you usually don&amp;rsquo;t have it) before jumping in to shine a light on how you think things could be done or fixed.&lt;/li&gt;
&lt;li&gt;Make sure you &lt;em&gt;fully understand the issue at hand&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Think about the ramifications of a poor decision&lt;/em&gt;: the higher the stakes are, the more likely it is that you should/could intervene.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Contemplate your role&lt;/em&gt;: depending on the relationship you have with that person, tolerance levels will change (personal note: ask questions early as needed, but make sure you show progress as stagnation won&amp;rsquo;t lead to joyful relationships with your colleagues and may get you fired).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;It&amp;rsquo;s OK to fail and it&amp;rsquo;s OK to feel bummed about it&lt;/strong&gt;. See how core/important the task is for the company, whether somebody else would be better positioned to do it, how long it would take you to become good at it, whether you enjoy it, whether there&amp;rsquo;s another way to solve the problem, if there&amp;rsquo;s someone else at the company who could teach you. Don&amp;rsquo;t beat yourself up with despair: be strategic about the way you spend you efforts.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Admit your weaknesses&amp;hellip; and own them&lt;/strong&gt;.
&lt;ul&gt;
&lt;li&gt;Is it something innate, like bluntness, or is it something you can learn, like Python?&lt;/li&gt;
&lt;li&gt;If a weakness is related to a core competency needed for your job, be proactive in overcoming the obstacle or find another job that&amp;rsquo;s better suited to your skills.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="your-career"&gt;Your career&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Favor learning over earning&lt;/strong&gt;: take the job with the highest learning potential.
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Beware of stunting your growth by working alone&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;You will become more valuable to your future employers and have a better idea of what you like.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;You will never be in a better position to leave a bad job than before you start&lt;/strong&gt;: interviewing is a two-way street.
&lt;ul&gt;
&lt;li&gt;Do your research before accepting a job offer.&lt;/li&gt;
&lt;li&gt;Investigate through your network, e.g. LinkedIn, if you have a connection that worked at that company and ask about the good and bad of this organization.&lt;/li&gt;
&lt;li&gt;Ask good questions about the company during the interview.&lt;/li&gt;
&lt;li&gt;As an exception, you might want to consider getting your feet wet in the industry with your first job by being less picky, especially if the job market is bad. Experience will prove useful.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pick a flaw&lt;/strong&gt;: no company is perfect.
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;You don&amp;rsquo;t want an indifferent team&lt;/em&gt; just punching the clock and waiting for the week to be done.&lt;/li&gt;
&lt;li&gt;Avoid nonsense: ask how a typical day goes, who makes decisions about priorities, in what kinds of projects does the company shine and what the best and worst parts of a job are.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Preparing for a recruiting event&lt;/strong&gt;. Have: a resume; a good intro to yourself; a good conversation you can have; be well presented.
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Resume&lt;/em&gt;: make sure you have the address, phone, email, GPA and graduation date (for students) at the top. It should show you&amp;rsquo;re motivated, skilled, passionate, adaptable, collaborative and articulate. When you have less experience, projects should be the centerpiece of your resume. Project descriptions should be brief and focus on the &lt;em&gt;what&lt;/em&gt;, &lt;em&gt;why&lt;/em&gt; and the outcome, avoiding mentions of tech stack unless it adds to the narrative. These can be side hustles, open source, personal interest or hackathons. Have more than one resume for different audiences.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Practice programming&lt;/strong&gt;: &lt;em&gt;you learn by doing&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Start at a consulting company if you&amp;rsquo;re looking to gain experience across technologies, domains and businesses. Work for a small one if you want to have an impact. This will provide contacts and set you up for future work. Seek out mentorship, request conference attendance and pursue assistance as formal education programs tend to be lacking in those environments.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Potential vs. delivery&lt;/strong&gt;: Ask smart questions, show you&amp;rsquo;ve learned stuff. Say what you&amp;rsquo;re going to do, then do it.
&lt;ul&gt;
&lt;li&gt;The more experienced you become, the more you are assessed on your &lt;em&gt;ability to deliver&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Expect to demonstrate your experience during interviews.&lt;/li&gt;
&lt;li&gt;Periodically, or when you complete a project, take a few minutes to &lt;em&gt;write some lessons you&amp;rsquo;ve learned&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Take risks early&lt;/em&gt; as pivoting later on in your career becomes more difficult.&lt;/li&gt;
&lt;li&gt;Book recommendation for more senior developers when switching domains, tech stacks or employers: &lt;a href="https://www.parachutebook.com/"&gt;What Color Is Your Parachute&lt;/a&gt;, by Richard N. Bolles, with Katherine Brooks.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Maintain work-life balance&lt;/strong&gt;: preserve a firm boundary. &lt;em&gt;Work is a marathon, not a sprint&lt;/em&gt;.
&lt;ul&gt;
&lt;li&gt;Get clear on how the employer expects you to handle unplanned work with conflicting priorities.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Listen to the voices when they help and ignore them when they don&amp;rsquo;t&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Be willing to do things you didn&amp;rsquo;t think you wanted to do&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Connect with non-tech people outside of work to take a break and experience life from their point of view too.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Manage your career&lt;/strong&gt;: &lt;em&gt;know your goals&lt;/em&gt;; &lt;em&gt;communicate your goals&lt;/em&gt;; &lt;em&gt;progress towards them&lt;/em&gt;.
&lt;ul&gt;
&lt;li&gt;Knowledge: pick an interest and follow it. Plan for a decade or more, with some milestones in between.&lt;/li&gt;
&lt;li&gt;Communication: communicate your desires and ambitions. Good companies want to see their employees grow.&lt;/li&gt;
&lt;li&gt;Progress: study for a certification, read a book, go to a meetup. Be active.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Know your runway&lt;/strong&gt;: this is the time you have at your current spending until you have no money. Calculate it once a month and know how long it would take to get a new job (guess).
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Get a job before you need to&lt;/em&gt; to avoid accepting an ill-fitting job due to desperation.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Cutting expenses&lt;/em&gt; is hard but it&amp;rsquo;s where you usually have the most control.&lt;/li&gt;
&lt;li&gt;Spending savings for a career transition is an &lt;em&gt;investment&lt;/em&gt; in yourself.&lt;/li&gt;
&lt;li&gt;Activities that draw down your savings should lead to new opportunities and valuable personal knowledge.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Managing one on ones&lt;/strong&gt;: for remote ones, it&amp;rsquo;s best to have a &lt;em&gt;great Internet connection&lt;/em&gt;, a &lt;em&gt;quiet space&lt;/em&gt; and &lt;em&gt;video turned on&lt;/em&gt; (personal note: you do lose visual clues without video, but you can connect deeply without anyone being too self-aware with voice-only communication).
&lt;ul&gt;
&lt;li&gt;Regular ones (weekly or bi-weekly) are preferred so you don&amp;rsquo;t dread feedback only when you ask for a raise or do something wrong. Knowing your manager beyond these scenarios will help.&lt;/li&gt;
&lt;li&gt;Reasons to schedule them: understand where we are headed so I know what to learn; know how I can best help the manager and the company; understand your priorities better.&lt;/li&gt;
&lt;li&gt;The direction of the one on one should be &lt;em&gt;determined by the employee&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Shoot for &lt;em&gt;regular&lt;/em&gt; ones that &lt;em&gt;do not get re-scheduled&lt;/em&gt;. Otherwise, propose having them less frequently if needed.&lt;/li&gt;
&lt;li&gt;If one-on-one meetings aren&amp;rsquo;t desirable, go for an asynchronous &lt;em&gt;weekly status report&lt;/em&gt; and get feedback from your manager this way: &lt;em&gt;it is critical for your career growth early on in your career&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Come with a &lt;em&gt;prepared agenda&lt;/em&gt; to make the most of them. A shared document in reverse chronological order works well. Example questions to add:
&lt;ul&gt;
&lt;li&gt;How should I have handled situation &lt;code&gt;X&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;I would like to learn more about &lt;code&gt;Y&lt;/code&gt;; what are the opportunities?&lt;/li&gt;
&lt;li&gt;I&amp;rsquo;m struggling with &lt;code&gt;&amp;lt;problem&amp;gt;&lt;/code&gt;, do you have any suggestions?&lt;/li&gt;
&lt;li&gt;What are the challenges you see facing our team during project &lt;code&gt;Z&lt;/code&gt;?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;You should be able to &lt;em&gt;trust and rely on your manager/boss&lt;/em&gt;. If not, improve the relationship or go elsewhere: being constantly under threat and not knowing what to expect is mentally draining.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Write a brag document&lt;/strong&gt;: show everything you&amp;rsquo;re proud of so they know you&amp;rsquo;re a great team member. It should be thorough yet easy to read. Along with the agendas from your one-on-one meetings, it will serve to highlight your accomplishments for your next performance review.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Be adaptable and authentic&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Working remotely&lt;/strong&gt;: you need a &lt;em&gt;fast Internet connection&lt;/em&gt;; &lt;em&gt;iron discipline&lt;/em&gt;; be okay with &lt;em&gt;solitude&lt;/em&gt; and have the &lt;em&gt;ability to work through communication obstacles&lt;/em&gt;.
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;If you are comfortable asking a dumb question, remote work can work well for you&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;You will need to &lt;em&gt;get used to asking questions and interrupting others&lt;/em&gt; as you more often than not won&amp;rsquo;t have enough context to infer whether it&amp;rsquo;s a good time to ask or not. It&amp;rsquo;s better than the alternative of wasting your time.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;How to go through a layoff&lt;/strong&gt;: &lt;em&gt;this isn&amp;rsquo;t personal and you will get through it&lt;/em&gt;.
&lt;ul&gt;
&lt;li&gt;Ask questions:
&lt;ul&gt;
&lt;li&gt;Know the deadline to sign the necessary documents;&lt;/li&gt;
&lt;li&gt;Find out if there&amp;rsquo;s a severance and how much is it;&lt;/li&gt;
&lt;li&gt;What about funds like 401k, FSA or HSA;&lt;/li&gt;
&lt;li&gt;How can I say goodbye to teammates (emails and LinkedIn are good options);&lt;/li&gt;
&lt;li&gt;What about company&amp;rsquo;s property, e.g. laptop, books and equipments;&lt;/li&gt;
&lt;li&gt;Who can I contact if have I more questions;&lt;/li&gt;
&lt;li&gt;Make sure they have your personal email;&lt;/li&gt;
&lt;li&gt;Take notes of what happened;&lt;/li&gt;
&lt;li&gt;Get involved with a lawyer before signing anything (e.g. non-compete agreements).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use LinkedIn&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;Send a note when you connect and keep in touch with past colleagues.&lt;/li&gt;
&lt;li&gt;Ask recruiters about the job market, salary ranges for people with your experience and good skills to learn.&lt;/li&gt;
&lt;li&gt;Review your connections&amp;rsquo; companies, review posted jobs and ask for introductions from your connections (let them know why the company is awesome, why you&amp;rsquo;re awesome and why you want to work there).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Contracting&lt;/strong&gt;: try it during the first decade of your career.
&lt;ul&gt;
&lt;li&gt;It&amp;rsquo;s easier than applying for a full-time job given you&amp;rsquo;re easier to let go.&lt;/li&gt;
&lt;li&gt;It will keep your skills sharp if you want to find clients.&lt;/li&gt;
&lt;li&gt;If/when you&amp;rsquo;re an employee again, job hunting won&amp;rsquo;t feel as scary.&lt;/li&gt;
&lt;li&gt;You will &lt;em&gt;strengthen your network&lt;/em&gt; by being able to refer former colleagues.&lt;/li&gt;
&lt;li&gt;Contracting can be more lucrative on a per-hour basis.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Contracting via an agency&lt;/em&gt; is easier (you avoid sales and accounting) but it pays less.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Direct contracting&lt;/em&gt; is harder but you&amp;rsquo;ll learn beyond software development (sales, customer support, marketing, invoicing and chasing payments). It leads to more control over the clients you work with and more income. You may spend as much as 50% of your time on non-billable work such as seeking new opportunities: your rate needs to reflect this.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Engineering management&lt;/strong&gt;: if you move to a management position, &lt;em&gt;be prepared to be a novice again&lt;/em&gt; as the skill set involved is not the same.
&lt;ul&gt;
&lt;li&gt;You should understand the code but &lt;em&gt;keep out of the critical path&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;You shouldn&amp;rsquo;t make technical decisions&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;You are here to &lt;em&gt;enable teams to do great work&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;The fun, technical stuff should only be done during hackathons.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Be clear about what you want&lt;/em&gt; and &lt;em&gt;maintain the right set of skills&lt;/em&gt; so you can keep doing what you enjoy the most.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Someday, you won&amp;rsquo;t want to code for a living&lt;/strong&gt;: becoming a manager gives you leverage to have more impact in the world.
&lt;ul&gt;
&lt;li&gt;Impact can be achieved through writing, project management, product management, speaking, starting a business, mentoring, leading a team, managing, teaching, architecting and consulting. Notice that coding is not the primary output.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="community"&gt;Community&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Building a community/network puts you in a situation where &lt;strong&gt;you can help people help others&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Meetups&lt;/strong&gt;: find one on &lt;a href="https://www.meetup.com/"&gt;meetup.com&lt;/a&gt;.
&lt;ul&gt;
&lt;li&gt;It will expose you to &lt;em&gt;new ideas&lt;/em&gt; you can bring to your job.&lt;/li&gt;
&lt;li&gt;You can have &lt;em&gt;professional conversations with low stakes&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;It gives you a way to &lt;em&gt;practice talking&lt;/em&gt; to new people and &lt;em&gt;make friends&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;It provides a network outside of your coworkers should you need to &lt;em&gt;find a new job&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Conversational hooks&lt;/strong&gt;: give some details about where you work and what projects you have been working on to give the chance to the other person to steer the conversation in the direction they want. Flip the question to ask people to talk about themselves (most people like to do that).
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Don&amp;rsquo;t make transactional conversations&lt;/em&gt;: find something interesting to talk about.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Online tech communities&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Sign up for an email list&lt;/em&gt; related to the technologies you are interested in. &lt;em&gt;Sign up for notifications on projects&lt;/em&gt;. You can &lt;em&gt;follow project contributors on Twitter&lt;/em&gt; or other social media places.&lt;/li&gt;
&lt;li&gt;For something more general, have a look on &lt;em&gt;Slack&lt;/em&gt;, &lt;em&gt;forums&lt;/em&gt;, &lt;em&gt;IRC channels&lt;/em&gt;, &lt;em&gt;Facebook groups&lt;/em&gt; and so on. &lt;em&gt;Slashdot&lt;/em&gt;, &lt;em&gt;Hacker News&lt;/em&gt;, &lt;em&gt;Reddit&lt;/em&gt;, &lt;em&gt;Stack Overflow&lt;/em&gt; are other good options.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;You get what you give&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;Offering to help &lt;em&gt;makes you more empathetic&lt;/em&gt; and &lt;em&gt;aware of other people&amp;rsquo;s needs&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;It feels good to help&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;You become less arrogant&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;You help &lt;em&gt;build the positivity of the community&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;People will be quicker to &lt;em&gt;recommend you for a job&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;It improves your &lt;em&gt;sense of self-worth&lt;/em&gt; and &lt;em&gt;confidence&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Build your work community&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;Use &lt;em&gt;LinkedIn&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Never leave a job on bad terms&lt;/em&gt;. Give the requisite notice, document your work and prepare for a hand off.&lt;/li&gt;
&lt;li&gt;Keep in touch with past coworkers, even if it&amp;rsquo;s just to leave a note on their work anniversary.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Three daily mantras&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Surround yourself with people smarter than you&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Build community and give without expecting anything in return&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Listen to your gut, without exception&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Build a personal board of advisors&lt;/strong&gt;.
&lt;ul&gt;
&lt;li&gt;Some issues you can discuss with them that aren&amp;rsquo;t topics for current coworkers:
&lt;ul&gt;
&lt;li&gt;Someone under your supervision is not succeeding;&lt;/li&gt;
&lt;li&gt;You have an issue with your manager that you&amp;rsquo;re not sure how to solve;&lt;/li&gt;
&lt;li&gt;You are evaluating job offers.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Make sure to keep these relationships fresh and &lt;em&gt;offer to help too&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;This circle shifts over time&lt;/em&gt;: a new developer doesn&amp;rsquo;t have the same questions that a team lead would have.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;That&amp;rsquo;s it: we went through a short overview of a book I&amp;rsquo;ve enjoyed and recommend heartily. You can find more on &lt;a href="https://letterstoanewdeveloper.com/"&gt;the author&amp;rsquo;s website&lt;/a&gt;. You might also enjoy a follow-up book summary about &lt;a href="https://www.sglavoie.com/posts/book-summary-the-effective-engineer/"&gt;The Effective Engineer&lt;/a&gt;. May you live this knowledge!&lt;/p&gt;</content:encoded><dc:creator>Sébastien Lavoie</dc:creator><pubDate>Mon, 08 Nov 2021 10:12:00 -0600</pubDate><guid isPermaLink="false">https://www.sglavoie.com/posts/book-summary-letters-to-a-new-developer/</guid><category>learnings</category><category>advice</category><category>best practices</category><category>books</category><category>career</category></item></channel></rss>