|
| 1 | +<meta name="id" content="6165535919949189914"> |
| 2 | +<meta name="labels" content="go,programming languages"> |
| 3 | +<meta name="title" content="Go Distilled"> |
| 4 | +<meta name="description" content="A terse guide for beginners in go to writing and organizing idiomatic go code for non-trivial programs."> |
| 5 | + |
| 6 | +Go (or "golang") is a [loosely object-oriented](https://golang.org/doc/faq#Is_Go_an_object-oriented_language), natively compiled language biased towards C-like simplicity, speed, and network applications. Its original authors, in a reaction to C++'s ever-growing feature set, created Go from the philosophy that ["less is more"](https://commandcenter.blogspot.com/2012/06/less-is-exponentially-more.html). Pragmatic and productive for large teams, it emphasises fast compile times and simple but productive abstractions like garbage collection, [structural typing](https://en.wikipedia.org/wiki/Structural_type_system), and namesake first class support for concurrent functions, {goroutines}. |
| 7 | + |
| 8 | +Getting started with Go typically involves... |
| 9 | + |
| 10 | +* An [interactive language tour]() (recommended) |
| 11 | +* Reading [How to Write Code in Go]() |
| 12 | +* Reading [Effective Go]() |
| 13 | + |
| 14 | +This aims to cover that material (I'll often quote it) and more, as tersely as possible, to get you productive in Go, quickly. We'll start with a quick demonstration of the basics, and then move to a practical, real-world guide to starting and contributing to real Go programs. |
| 15 | + |
| 16 | +## A quick tour of the basic syntax |
| 17 | + |
| 18 | +C family. Types inferred. Use tabs not spaces. Redundant symbols are often optional like parentheses in for loops, or semicolons. A few built-in features like collections or channels or type switches have special syntax. No line length limit, but be reasonable. Built-in auto-formatter, because we are not barbarians, after all. |
| 19 | + |
| 20 | +// If you want to explore the syntax with an interactive editor, check out the [official language tour](https://tour.golang.org/). |
| 21 | + |
| 22 | +### Comments, documentation, variables, and assignments |
| 23 | + |
| 24 | +Comments that immediately precede top-level declarations which be included in generated documentation (via [godoc](https://blog.golang.org/godoc)). Others will not. |
| 25 | + |
| 26 | +// Beginning this post with how to write good documentation was no accident! |
| 27 | + |
| 28 | +Documentation comments have simple syntax. Mostly, just write plain text markup: |
| 29 | + |
| 30 | +* For code blocks (or other preformatted text), indent those lines. |
| 31 | +* Links will automatically create hyperlinks. |
| 32 | +* Headings are lone lines that start with capital letter, precede a paragraph, and contain no punctuation other than parentheses or commas |
| 33 | +* Example code has [first class support](https://golang.org/pkg/testing/#hdr-Examples) in godoc, but understanding how that works requires a bit more understanding about package layout and testing, so we'll come back to this below `TODO add link`. |
| 34 | + |
| 35 | +```go |
| 36 | +// Not included in documentation (does not precede a declaration). |
| 37 | + |
| 38 | +// This comment is documentation. |
| 39 | +// |
| 40 | +// Heading |
| 41 | +// |
| 42 | +// This is a paragraph under that heading. |
| 43 | +// |
| 44 | +// // Indent code like you would in markdown. |
| 45 | +var x int = 1 |
| 46 | +``` |
| 47 | + |
| 48 | +Above and below show variables with an **explicitly declared type and initializer**. This is **uncommon** unless the inferred type would be inappropriate. |
| 49 | + |
| 50 | +```go |
| 51 | +// Would infer int, but x is a float32 because we explicitly said so. |
| 52 | +var x float32 = 1 |
| 53 | +``` |
| 54 | + |
| 55 | +**Variables may be uninitialized**: simply omit the equals and value. **Uninitialized variables start with a [{{zero value}}](https://golang.org/ref/spec#The_zero_value)**. For basic types the zero value is generally what you might expect, particularly if you are coming from Java: numeric types get 0, booleans get false, strings get the empty string. |
| 56 | + |
| 57 | +```go |
| 58 | +var x int // initialized to 0. |
| 59 | +``` |
| 60 | + |
| 61 | +As alluded to above, **if you have an initial value, the type can be inferred**. In this case, it's common to use the {{short assignment}} syntax shown below, but this only works inside functions, because [top-level declarations must start with a keyword](https://groups.google.com/forum/#!msg/golang-nuts/qTZemuGDV6o/IyCwXPJsUFIJ). For top-level declarations, you can still omit the type, you just have to keep `var`. |
| 62 | + |
| 63 | +```go |
| 64 | +// Short assignment, not usable outside functions |
| 65 | +x := 1 |
| 66 | + |
| 67 | +// Starts with keyword, so usable top-level; prefer short assignment inside functions |
| 68 | +var y = 2 |
| 69 | +``` |
| 70 | + |
| 71 | +You may also **declare multiple variables together**, which is useful for grouping related variables, since, other than |
| 72 | +obviously appearing together inside parenthesis, [doc comments apply to the entire group as a unit](https://golang.org/doc/effective_go.html#commentary). |
| 73 | + |
| 74 | +```go |
| 75 | +// Doc comments on grouped variable declarations document the whole group as a unit. |
| 76 | +var ( |
| 77 | + ErrInternal = errors.New("regexp: internal error") |
| 78 | + ErrUnmatchedLpar = errors.New("regexp: unmatched '('") |
| 79 | + ErrUnmatchedRpar = errors.New("regexp: unmatched ')'") |
| 80 | +) |
| 81 | +``` |
| 82 | + |
| 83 | +Another way to declare multiple variables at once is to **list them comma delimited.** In this case however the variables **must share the same type, or all use inferred types**. |
| 84 | + |
| 85 | +```go |
| 86 | +var x, y = 1, 2 |
| 87 | + |
| 88 | +// Short assignment works inside functions as above |
| 89 | +x, y := 1, 2 |
| 90 | + |
| 91 | +// Explicit type works too if needed |
| 92 | +var a, b string = "a", "b" |
| 93 | +``` |
| 94 | + |
| 95 | +As we'll see shortly, functions may return multiple values. In that case, you'll use the comma delimited syntax above to assign each value. |
| 96 | + |
| 97 | +```go |
| 98 | +results, err := search("go distilled") |
| 99 | +``` |
| 100 | + |
| 101 | +### Basic types |
| 102 | + |
| 103 | +The following snippet demonstrates the basic types in go. |
| 104 | + |
| 105 | +```go |
| 106 | +var funLanguage bool = true |
| 107 | +var itIsUtf8 string = "こんにちは" |
| 108 | +var sizedBasedOnPlatform int = 1 |
| 109 | +var explicitSize int32 = 2 |
| 110 | +var unsigned uint = 3 |
| 111 | +var bitsAndBytes byte = 0 |
| 112 | +var floatingPoint float32 = 1.234 |
| 113 | +``` |
| 114 | + |
| 115 | +Numeric type bit widths may be 8, 16, 32, or 64. Just use the default (e.g. `int`) unless you have a good reason otherwise. |
| 116 | + |
| 117 | +### Functions |
| 118 | + |
| 119 | +As in variables, **types follow names**. This function, named "greeting", accepts a string named "who" and returns a string. |
| 120 | + |
| 121 | +```go |
| 122 | +func greeting(who string) string { |
| 123 | + return "Hello, " + who + "!" |
| 124 | +} |
| 125 | +``` |
| 126 | + |
| 127 | +As mentioned above, **functions may return multiple values**, often used for error handling, since go does not have traditional exceptions like Java or Python. (See introductory points on minimalism.) |
| 128 | + |
| 129 | +```go |
| 130 | +func greeting(who string) (string, int) { |
| 131 | + return "Hello", len([]rune(who)) |
| 132 | +} |
| 133 | +``` |
| 134 | + |
| 135 | +**Return values may also be named**. Sometimes this makes their intent clear. |
| 136 | + |
| 137 | +```go |
| 138 | +func greeting(who string) (greeting string, whoLength int) { |
| 139 | + return "Hello", len([]rune(who)) |
| 140 | +} |
| 141 | +``` |
| 142 | + |
| 143 | +**Named return variables can actually be assigned by name**, and returned via a {{naked |
| 144 | +return}}. This is occasionally useful in short functions, as in this example from |
| 145 | +[Effective Go](https://golang.org/doc/effective_go.html#named-results). **Not recommended in longer functions** for obvious reasons. |
| 146 | + |
| 147 | +```go |
| 148 | +func ReadFull(r Reader, buf []byte) (n int, err error) { |
| 149 | + for len(buf) > 0 && err == nil { |
| 150 | + var nr int |
| 151 | + nr, err = r.Read(buf) |
| 152 | + n += nr |
| 153 | + buf = buf[nr:] |
| 154 | + } |
| 155 | + return |
| 156 | +} |
| 157 | +``` |
| 158 | + |
| 159 | +### Collections |
| 160 | + |
| 161 | +#### Arrays and slices (lists) |
| 162 | + |
| 163 | + |
| 164 | + |
| 165 | +#### Maps |
| 166 | + |
| 167 | +### Flow control |
| 168 | + |
| 169 | +```go |
| 170 | + |
| 171 | +``` |
| 172 | + |
| 173 | +### Pointers |
| 174 | + |
| 175 | +## Concurrency |
| 176 | + |
| 177 | +* goroutines |
| 178 | +* channels |
| 179 | +* shared memory semantics |
| 180 | +* context passing |
| 181 | + |
| 182 | +## Go in practice |
| 183 | + |
| 184 | +### Object-oriented Go |
| 185 | + |
| 186 | +* Type definitions |
| 187 | +* Structs – note documenting structs (whole struct appears in docs), good zero types |
| 188 | + |
| 189 | + |
| 190 | +// For a more advanced understanding of how to use the zero value effectively, see [What is the zero value, and why is it useful?](https://dave.cheney.net/2013/01/19/what-is-the-zero-value-and-why-is-it-useful) |
| 191 | + |
| 192 | +* Interfaces |
| 193 | +* Methods (extension methods) |
| 194 | +* Casts |
| 195 | + |
| 196 | +### Organization: modules, packages, visibility, and repository layout |
| 197 | + |
| 198 | + |
| 199 | + |
| 200 | + |
| 201 | +### Enums and `iota` |
| 202 | + |
| 203 | +https://github.com/golang/go/wiki/Iota |
| 204 | + |
| 205 | + |
| 206 | + |
0 commit comments