Robert Griesemer | 53440da | 2009-10-01 14:08:00 -0700 | [diff] [blame] | 1 | <!-- Go For C++ Programmers --> |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 2 | |
| 3 | <p> |
Russ Cox | 2a63f5d | 2009-11-08 01:08:26 -0800 | [diff] [blame] | 4 | Go is a systems programming language intended to be a general-purpose |
| 5 | systems language, like C++. |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 6 | These are some notes on Go for experienced C++ programmers. This |
| 7 | document discusses the differences between Go and C++, and says little |
| 8 | to nothing about the similarities. |
| 9 | |
| 10 | <p> |
| 11 | For a more general introduction to Go, see the |
Rob Pike | 6ac19ec | 2009-11-01 20:57:13 -0800 | [diff] [blame] | 12 | <a href="go_tutorial.html">Go tutorial</a> and |
| 13 | <a href="effective_go.html">Effective Go</a>. |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 14 | |
| 15 | <p> |
| 16 | For a detailed description of the Go language, see the |
| 17 | <a href="go_spec.html">Go spec</a>. |
| 18 | |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 19 | <h2 id="Conceptual_Differences">Conceptual Differences</h2> |
| 20 | |
| 21 | <ul> |
| 22 | <li>Go does not have classes with constructors or destructors. |
| 23 | Instead of class methods, a class inheritance hierarchy, |
| 24 | and virtual functions, Go provides <em>interfaces</em>, which are |
| 25 | <a href="#Interfaces">discussed in more detail below</a>. |
| 26 | Interfaces are also used where C++ uses templates. |
| 27 | |
Russ Cox | 2a63f5d | 2009-11-08 01:08:26 -0800 | [diff] [blame] | 28 | <li>Go uses garbage collection. It is not necessary (or possible) |
| 29 | to release memory explicitly. The garbage collection is (intended to be) |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 30 | incremental and highly efficient on modern processors. |
| 31 | |
Russ Cox | 2a63f5d | 2009-11-08 01:08:26 -0800 | [diff] [blame] | 32 | <li>Go has pointers but not pointer arithmetic. You cannot |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 33 | use a pointer variable to walk through the bytes of a string. |
| 34 | |
| 35 | <li>Arrays in Go are first class values. When an array is used as a |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 36 | function parameter, the function receives a copy of the array, not |
| 37 | a pointer to it. However, in practice functions often use slices |
| 38 | for parameters; slices hold pointers to underlying arrays. Slices |
| 39 | are <a href="#Slices">discussed further below</a>. |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 40 | |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 41 | <li>Strings are provided by the language. They may not be changed once they |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 42 | have been created. |
| 43 | |
| 44 | <li>Hash tables are provided by the language. They are called maps. |
| 45 | |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 46 | <li>Separate threads of execution, and communication channels between |
| 47 | them, are provided by the language. This |
| 48 | is <a href="#Goroutines">discussed further below</a>. |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 49 | |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 50 | <li>Certain types (maps and channels, described further below) |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 51 | are passed by reference, not by value. That is, passing a map to a |
| 52 | function does not copy the map, and if the function changes the map |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 53 | the change will be seen by the caller. In C++ terms, one can |
| 54 | think of these as being reference types. |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 55 | |
| 56 | <li>Go does not use header files. Instead, each source file is part of a |
| 57 | defined <em>package</em>. When a package defines an object |
Rob Pike | 6ac19ec | 2009-11-01 20:57:13 -0800 | [diff] [blame] | 58 | (type, constant, variable, function) with a name starting with an |
| 59 | upper case letter, that object is visible to any other file which |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 60 | imports that package. |
| 61 | |
| 62 | <li>Go does not support implicit type conversion. Operations that mix |
| 63 | different types require casts (called conversions in Go). |
| 64 | |
| 65 | <li>Go does not support function overloading and does not support user |
| 66 | defined operators. |
| 67 | |
| 68 | <li>Go does not support <code>const</code> or <code>volatile</code> qualifiers. |
| 69 | |
| 70 | <li>Go uses <code>nil</code> for invalid pointers, where C++ uses |
| 71 | <code>NULL</code> or simply <code>0</code>. |
| 72 | </ul> |
| 73 | |
| 74 | <h2 id="Syntax">Syntax</h2> |
| 75 | |
| 76 | <p> |
| 77 | The declaration syntax is reversed compared to C++. You write the name |
Russ Cox | 2a63f5d | 2009-11-08 01:08:26 -0800 | [diff] [blame] | 78 | followed by the type. Unlike in C++, the syntax for a type does not match |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 79 | the way in which the variable is used. Type declarations may be read |
| 80 | easily from left to right. |
| 81 | |
| 82 | <pre> |
| 83 | <b>Go C++</b> |
Ian Lance Taylor | bf57520 | 2010-01-29 16:37:50 -0800 | [diff] [blame] | 84 | var v1 int // int v1; |
| 85 | var v2 string // const std::string v2; (approximately) |
| 86 | var v3 [10]int // int v3[10]; |
| 87 | var v4 []int // int* v4; (approximately) |
| 88 | var v5 struct { f int } // struct { int f; } v5; |
| 89 | var v6 *int // int* v6; (but no pointer arithmetic) |
| 90 | var v7 map[string]int // unordered_map<string, int>* v7; (approximately) |
| 91 | var v8 func(a int) int // int (*v8)(int a); |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 92 | </pre> |
| 93 | |
| 94 | <p> |
| 95 | Declarations generally take the form of a keyword followed by the name |
| 96 | of the object being declared. The keyword is one of <code>var</code>, |
| 97 | <code>func</code>, |
| 98 | <code>const</code>, or <code>type</code>. Method declarations are a minor |
| 99 | exception in that |
Russ Cox | 2a63f5d | 2009-11-08 01:08:26 -0800 | [diff] [blame] | 100 | the receiver appears before the name of the object being declared; see |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 101 | the <a href="#Interfaces">discussion of interfaces</a>. |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 102 | |
| 103 | <p> |
| 104 | You can also use a keyword followed by a series of declarations in |
| 105 | parentheses. |
| 106 | |
| 107 | <pre> |
Russ Cox | 2a63f5d | 2009-11-08 01:08:26 -0800 | [diff] [blame] | 108 | var ( |
Ian Lance Taylor | bf57520 | 2010-01-29 16:37:50 -0800 | [diff] [blame] | 109 | i int |
Rob Pike | 80e25fc | 2011-01-19 23:07:38 -0500 | [diff] [blame] | 110 | m float64 |
Russ Cox | 2a63f5d | 2009-11-08 01:08:26 -0800 | [diff] [blame] | 111 | ) |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 112 | </pre> |
| 113 | |
| 114 | <p> |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 115 | When declaring a function, you must either provide a name for each parameter |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 116 | or not provide a name for any parameter; you can't omit some names |
| 117 | and provide others. You may group several names with the same type: |
| 118 | |
| 119 | <pre> |
Ian Lance Taylor | bf57520 | 2010-01-29 16:37:50 -0800 | [diff] [blame] | 120 | func f(i, j, k int, s, t string) |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 121 | </pre> |
| 122 | |
| 123 | <p> |
| 124 | A variable may be initialized when it is declared. When this is done, |
| 125 | specifying the type is permitted but not required. When the type is |
| 126 | not specified, the type of the variable is the type of the |
| 127 | initialization expression. |
| 128 | |
| 129 | <pre> |
Ian Lance Taylor | bf57520 | 2010-01-29 16:37:50 -0800 | [diff] [blame] | 130 | var v = *p |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 131 | </pre> |
| 132 | |
| 133 | <p> |
| 134 | See also the <a href="#Constants">discussion of constants, below</a>. |
Russ Cox | 2a63f5d | 2009-11-08 01:08:26 -0800 | [diff] [blame] | 135 | If a variable is not initialized explicitly, the type must be specified. |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 136 | In that case it will be |
Russ Cox | 2a63f5d | 2009-11-08 01:08:26 -0800 | [diff] [blame] | 137 | implicitly initialized to the type's zero value (0, nil, etc.). There are no |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 138 | uninitialized variables in Go. |
| 139 | |
| 140 | <p> |
Russ Cox | 2a63f5d | 2009-11-08 01:08:26 -0800 | [diff] [blame] | 141 | Within a function, a short declaration syntax is available with |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 142 | <code>:=</code> . |
| 143 | |
| 144 | <pre> |
Ian Lance Taylor | bf57520 | 2010-01-29 16:37:50 -0800 | [diff] [blame] | 145 | v1 := v2 |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 146 | </pre> |
| 147 | |
| 148 | <p> |
| 149 | This is equivalent to |
| 150 | |
| 151 | <pre> |
Ian Lance Taylor | bf57520 | 2010-01-29 16:37:50 -0800 | [diff] [blame] | 152 | var v1 = v2 |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 153 | </pre> |
| 154 | |
| 155 | <p> |
Rob Pike | 6ac19ec | 2009-11-01 20:57:13 -0800 | [diff] [blame] | 156 | Go permits multiple assignments, which are done in parallel. |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 157 | |
| 158 | <pre> |
Ian Lance Taylor | bf57520 | 2010-01-29 16:37:50 -0800 | [diff] [blame] | 159 | i, j = j, i // Swap i and j. |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 160 | </pre> |
| 161 | |
| 162 | <p> |
Rob Pike | 6ac19ec | 2009-11-01 20:57:13 -0800 | [diff] [blame] | 163 | Functions may have multiple return values, indicated by a list in |
| 164 | parentheses. The returned values can be stored by assignment |
| 165 | to a list of variables. |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 166 | |
| 167 | <pre> |
Ian Lance Taylor | bf57520 | 2010-01-29 16:37:50 -0800 | [diff] [blame] | 168 | func f() (i int, j int) { ... } |
| 169 | v1, v2 = f() |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 170 | </pre> |
| 171 | |
| 172 | <p> |
Ian Lance Taylor | bf57520 | 2010-01-29 16:37:50 -0800 | [diff] [blame] | 173 | Go code uses very few semicolons in practice. Technically, all Go |
| 174 | statements are terminated by a semicolon. However, Go treats the end |
| 175 | of a non-blank line as a semicolon unless the line is clearly |
| 176 | incomplete (the exact rules are |
| 177 | in <a href="go_spec.html#Semicolons">the language specification</a>). |
| 178 | A consequence of this is that in some cases Go does not permit you to |
| 179 | use a line break. For example, you may not write |
| 180 | <pre> |
| 181 | func g() |
| 182 | { // INVALID |
| 183 | } |
| 184 | </pre> |
| 185 | A semicolon will be inserted after <code>g()</code>, causing it to be |
| 186 | a function declaration rather than a function definition. Similarly, |
| 187 | you may not write |
| 188 | <pre> |
| 189 | if x { |
| 190 | } |
| 191 | else { // INVALID |
| 192 | } |
| 193 | </pre> |
| 194 | A semicolon will be inserted after the <code>}</code> preceding |
| 195 | the <code>else</code>, causing a syntax error. |
| 196 | |
| 197 | <p> |
| 198 | Since semicolons do end statements, you may continue using them as in |
| 199 | C++. However, that is not the recommended style. Idiomatic Go code |
| 200 | omits unnecessary semicolons, which in practice is all of them other |
Scott Lawrence | 76dccbc | 2010-08-30 09:58:27 +1000 | [diff] [blame] | 201 | than the initial <code>for</code> loop clause and cases where you want several |
Ian Lance Taylor | bf57520 | 2010-01-29 16:37:50 -0800 | [diff] [blame] | 202 | short statements on a single line. |
| 203 | |
| 204 | <p> |
| 205 | While we're on the topic, we recommend that rather than worry about |
| 206 | semicolons and brace placement, you format your code with |
| 207 | the <code>gofmt</code> program. That will produce a single standard |
| 208 | Go style, and let you worry about your code rather than your |
| 209 | formatting. While the style may initially seem odd, it is as good as |
| 210 | any other style, and familiarity will lead to comfort. |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 211 | |
| 212 | <p> |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 213 | When using a pointer to a struct, you use <code>.</code> instead |
| 214 | of <code>-></code>. |
| 215 | Thus syntactically speaking a structure and a pointer to a structure |
| 216 | are used in the same way. |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 217 | |
| 218 | <pre> |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 219 | type myStruct struct { i int } |
Ian Lance Taylor | bf57520 | 2010-01-29 16:37:50 -0800 | [diff] [blame] | 220 | var v9 myStruct // v9 has structure type |
| 221 | var p9 *myStruct // p9 is a pointer to a structure |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 222 | f(v9.i, p9.i) |
| 223 | </pre> |
| 224 | |
| 225 | <p> |
| 226 | Go does not require parentheses around the condition of a <code>if</code> |
| 227 | statement, or the expressions of a <code>for</code> statement, or the value of a |
| 228 | <code>switch</code> statement. On the other hand, it does require curly braces |
| 229 | around the body of an <code>if</code> or <code>for</code> statement. |
| 230 | |
| 231 | <pre> |
Ian Lance Taylor | bf57520 | 2010-01-29 16:37:50 -0800 | [diff] [blame] | 232 | if a < b { f() } // Valid |
| 233 | if (a < b) { f() } // Valid (condition is a parenthesized expression) |
| 234 | if (a < b) f() // INVALID |
| 235 | for i = 0; i < 10; i++ {} // Valid |
| 236 | for (i = 0; i < 10; i++) {} // INVALID |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 237 | </pre> |
| 238 | |
| 239 | <p> |
| 240 | Go does not have a <code>while</code> statement nor does it have a |
| 241 | <code>do/while</code> |
| 242 | statement. The <code>for</code> statement may be used with a single condition, |
| 243 | which makes it equivalent to a <code>while</code> statement. Omitting the |
| 244 | condition entirely is an endless loop. |
| 245 | |
| 246 | <p> |
| 247 | Go permits <code>break</code> and <code>continue</code> to specify a label. |
| 248 | The label must |
| 249 | refer to a <code>for</code>, <code>switch</code>, or <code>select</code> |
| 250 | statement. |
| 251 | |
| 252 | <p> |
| 253 | In a <code>switch</code> statement, <code>case</code> labels do not fall |
| 254 | through. You can |
| 255 | make them fall through using the <code>fallthrough</code> keyword. This applies |
| 256 | even to adjacent cases. |
| 257 | |
| 258 | <pre> |
Russ Cox | 2a63f5d | 2009-11-08 01:08:26 -0800 | [diff] [blame] | 259 | switch i { |
| 260 | case 0: // empty case body |
| 261 | case 1: |
| 262 | f() // f is not called when i == 0! |
| 263 | } |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 264 | </pre> |
| 265 | |
| 266 | <p> |
| 267 | But a <code>case</code> can have multiple values. |
| 268 | |
| 269 | <pre> |
Russ Cox | 2a63f5d | 2009-11-08 01:08:26 -0800 | [diff] [blame] | 270 | switch i { |
| 271 | case 0, 1: |
| 272 | f() // f is called if i == 0 || i == 1. |
| 273 | } |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 274 | </pre> |
| 275 | |
| 276 | <p> |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 277 | The values in a <code>case</code> need not be constants—or even integers; |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 278 | any type |
| 279 | that supports the equality comparison operator, such as strings or |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 280 | pointers, can be used—and if the <code>switch</code> |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 281 | value is omitted it defaults to <code>true</code>. |
| 282 | |
| 283 | <pre> |
Russ Cox | 2a63f5d | 2009-11-08 01:08:26 -0800 | [diff] [blame] | 284 | switch { |
| 285 | case i < 0: |
| 286 | f1() |
| 287 | case i == 0: |
| 288 | f2() |
| 289 | case i > 0: |
| 290 | f3() |
| 291 | } |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 292 | </pre> |
| 293 | |
| 294 | <p> |
| 295 | The <code>++</code> and <code>--</code> operators may only be used in |
| 296 | statements, not in expressions. |
| 297 | You cannot write <code>c = *p++</code>. <code>*p++</code> is parsed as |
| 298 | <code>(*p)++</code>. |
| 299 | |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 300 | <p> |
| 301 | The <code>defer</code> statement may be used to call a function after |
| 302 | the function containing the <code>defer</code> statement returns. |
| 303 | |
| 304 | <pre> |
Ian Lance Taylor | bf57520 | 2010-01-29 16:37:50 -0800 | [diff] [blame] | 305 | fd := open("filename") |
| 306 | defer close(fd) // fd will be closed when this function returns. |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 307 | </pre> |
| 308 | |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 309 | <h2 id="Constants">Constants </h2> |
| 310 | |
| 311 | <p> |
Robert Griesemer | a27f1f7 | 2009-10-01 14:12:18 -0700 | [diff] [blame] | 312 | In Go constants may be <i>untyped</i>. This applies even to constants |
Russ Cox | 2a63f5d | 2009-11-08 01:08:26 -0800 | [diff] [blame] | 313 | named with a <code>const</code> declaration, if no |
Robert Griesemer | a27f1f7 | 2009-10-01 14:12:18 -0700 | [diff] [blame] | 314 | type is given in the declaration and the initializer expression uses only |
| 315 | untyped constants. |
Rob Pike | 6ac19ec | 2009-11-01 20:57:13 -0800 | [diff] [blame] | 316 | A value derived from an untyped constant becomes typed when it |
| 317 | is used within a context that |
Robert Griesemer | a27f1f7 | 2009-10-01 14:12:18 -0700 | [diff] [blame] | 318 | requires a typed value. This permits constants to be used relatively |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 319 | freely without requiring general implicit type conversion. |
| 320 | |
| 321 | <pre> |
Ian Lance Taylor | bf57520 | 2010-01-29 16:37:50 -0800 | [diff] [blame] | 322 | var a uint |
Russ Cox | 2a63f5d | 2009-11-08 01:08:26 -0800 | [diff] [blame] | 323 | f(a + 1) // untyped numeric constant "1" becomes typed as uint |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 324 | </pre> |
| 325 | |
| 326 | <p> |
Robert Griesemer | a27f1f7 | 2009-10-01 14:12:18 -0700 | [diff] [blame] | 327 | The language does not impose any limits on the size of an untyped |
| 328 | numeric constant or constant expression. A limit is only applied when |
| 329 | a constant is used where a type is required. |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 330 | |
| 331 | <pre> |
Ian Lance Taylor | bf57520 | 2010-01-29 16:37:50 -0800 | [diff] [blame] | 332 | const huge = 1 << 100 |
Russ Cox | 2a63f5d | 2009-11-08 01:08:26 -0800 | [diff] [blame] | 333 | f(huge >> 98) |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 334 | </pre> |
| 335 | |
| 336 | <p> |
| 337 | Go does not support enums. Instead, you can use the special name |
| 338 | <code>iota</code> in a single <code>const</code> declaration to get a |
| 339 | series of increasing |
| 340 | value. When an initialization expression is omitted for a <code>const</code>, |
| 341 | it reuses the preceding expression. |
| 342 | |
| 343 | <pre> |
Russ Cox | 2a63f5d | 2009-11-08 01:08:26 -0800 | [diff] [blame] | 344 | const ( |
Ian Lance Taylor | bf57520 | 2010-01-29 16:37:50 -0800 | [diff] [blame] | 345 | red = iota // red == 0 |
| 346 | blue // blue == 1 |
Russ Cox | 2a63f5d | 2009-11-08 01:08:26 -0800 | [diff] [blame] | 347 | green // green == 2 |
| 348 | ) |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 349 | </pre> |
| 350 | |
| 351 | <h2 id="Slices">Slices</h2> |
| 352 | |
| 353 | <p> |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 354 | A slice is conceptually a struct with three fields: a |
| 355 | pointer to an array, a length, and a capacity. |
| 356 | Slices support |
| 357 | the <code>[]</code> operator to access elements of the underlying array. |
| 358 | The builtin |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 359 | <code>len</code> function returns the |
| 360 | length of the slice. The builtin <code>cap</code> function returns the |
| 361 | capacity. |
| 362 | |
| 363 | <p> |
| 364 | Given an array, or another slice, a new slice is created via |
| 365 | <code>a[I:J]</code>. This |
| 366 | creates a new slice which refers to <code>a</code>, starts at |
Russ Cox | 2a63f5d | 2009-11-08 01:08:26 -0800 | [diff] [blame] | 367 | index <code>I</code>, and ends before index |
| 368 | <code>J</code>. It has length <code>J - I</code>. |
Rob Pike | 6ac19ec | 2009-11-01 20:57:13 -0800 | [diff] [blame] | 369 | The new slice refers to the same array |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 370 | to which <code>a</code> |
| 371 | refers. That is, changes made using the new slice may be seen using |
| 372 | <code>a</code>. The |
| 373 | capacity of the new slice is simply the capacity of <code>a</code> minus |
| 374 | <code>I</code>. The capacity |
Russ Cox | 2a63f5d | 2009-11-08 01:08:26 -0800 | [diff] [blame] | 375 | of an array is the length of the array. You may also assign an array pointer |
| 376 | to a variable of slice type; given <code>var s []int; var a[10] int</code>, |
Andrey Mirtchovski | 9a44578 | 2010-03-09 14:21:34 -0800 | [diff] [blame] | 377 | the assignment <code>s = &a</code> is equivalent to |
Russ Cox | 2a63f5d | 2009-11-08 01:08:26 -0800 | [diff] [blame] | 378 | <code>s = a[0:len(a)]</code>. |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 379 | |
| 380 | <p> |
| 381 | What this means is that Go uses slices for some cases where C++ uses pointers. |
| 382 | If you create a value of type <code>[100]byte</code> (an array of 100 bytes, |
| 383 | perhaps a |
| 384 | buffer) and you want to pass it to a function without copying it, you should |
| 385 | declare the function parameter to have type <code>[]byte</code>, and pass the |
| 386 | address |
Russ Cox | 2a63f5d | 2009-11-08 01:08:26 -0800 | [diff] [blame] | 387 | of the array. Unlike in C++, it is not |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 388 | necessary to pass the length of the buffer; it is efficiently accessible via |
| 389 | <code>len</code>. |
| 390 | |
| 391 | <p> |
| 392 | The slice syntax may also be used with a string. It returns a new string, |
| 393 | whose value is a substring of the original string. |
Rob Pike | 6ac19ec | 2009-11-01 20:57:13 -0800 | [diff] [blame] | 394 | Because strings are immutable, string slices can be implemented |
| 395 | without allocating new storage for the slices's contents. |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 396 | |
| 397 | <h2 id="Making_values">Making values</h2> |
| 398 | |
| 399 | <p> |
| 400 | Go has a builtin function <code>new</code> which takes a type and |
| 401 | allocates space |
| 402 | on the heap. The allocated space will be zero-initialized for the type. |
Rob Pike | 6ac19ec | 2009-11-01 20:57:13 -0800 | [diff] [blame] | 403 | For example, <code>new(int)</code> allocates a new int on the heap, |
| 404 | initializes it with the value <code>0</code>, |
| 405 | and returns its address, which has type <code>*int</code>. |
| 406 | Unlike in C++, <code>new</code> is a function, not an operator; |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 407 | <code>new int</code> is a syntax error. |
| 408 | |
| 409 | <p> |
| 410 | Map and channel values must be allocated using the builtin function |
| 411 | <code>make</code>. |
| 412 | A variable declared with map or channel type without an initializer will be |
| 413 | automatically initialized to <code>nil</code>. |
| 414 | Calling <code>make(map[int]int)</code> returns a newly allocated value of |
| 415 | type <code>map[int]int</code>. |
| 416 | Note that <code>make</code> returns a value, not a pointer. This is |
| 417 | consistent with |
| 418 | the fact that map and channel values are passed by reference. Calling |
| 419 | <code>make</code> with |
| 420 | a map type takes an optional argument which is the expected capacity of the |
| 421 | map. Calling <code>make</code> with a channel type takes an optional |
Rob Pike | 6ac19ec | 2009-11-01 20:57:13 -0800 | [diff] [blame] | 422 | argument which sets the |
| 423 | buffering capacity of the channel; the default is 0 (unbuffered). |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 424 | |
| 425 | <p> |
| 426 | The <code>make</code> function may also be used to allocate a slice. |
| 427 | In this case it |
| 428 | allocates memory for the underlying array and returns a slice referring to it. |
| 429 | There is one required argument, which is the number of elements in the slice. |
| 430 | A second, optional, argument is the capacity of the slice. For example, |
| 431 | <code>make([]int, 10, 20)</code>. This is identical to |
| 432 | <code>new([20]int)[0:10]</code>. Since |
| 433 | Go uses garbage collection, the newly allocated array will be discarded |
| 434 | sometime after there are no references to the returned slice. |
| 435 | |
| 436 | <h2 id="Interfaces">Interfaces</h2> |
| 437 | |
| 438 | <p> |
Rob Pike | 6ac19ec | 2009-11-01 20:57:13 -0800 | [diff] [blame] | 439 | Where C++ provides classes, subclasses and templates, |
| 440 | Go provides interfaces. A |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 441 | Go interface is similar to a C++ pure abstract class: a class with no |
| 442 | data members, with methods which are all pure virtual. However, in |
| 443 | Go, any type which provides the methods named in the interface may be |
| 444 | treated as an implementation of the interface. No explicitly declared |
| 445 | inheritance is required. The implementation of the interface is |
| 446 | entirely separate from the interface itself. |
| 447 | |
| 448 | <p> |
| 449 | A method looks like an ordinary function definition, except that it |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 450 | has a <em>receiver</em>. The receiver is similar to |
| 451 | the <code>this</code> pointer in a C++ class method. |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 452 | |
| 453 | <pre> |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 454 | type myType struct { i int } |
| 455 | func (p *myType) get() int { return p.i } |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 456 | </pre> |
| 457 | |
| 458 | <p> |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 459 | This declares a method <code>get</code> associated with <code>myType</code>. |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 460 | The receiver is named <code>p</code> in the body of the function. |
| 461 | |
| 462 | <p> |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 463 | Methods are defined on named types. If you convert the value |
| 464 | to a different type, the new value will have the methods of the new type, |
| 465 | not the old type. |
| 466 | |
| 467 | <p> |
| 468 | You may define methods on a builtin type by declaring a new named type |
| 469 | derived from it. The new type is distinct from the builtin type. |
| 470 | |
| 471 | <pre> |
| 472 | type myInteger int |
| 473 | func (p myInteger) get() int { return int(p) } // Conversion required. |
| 474 | func f(i int) { } |
| 475 | var v myInteger |
| 476 | // f(v) is invalid. |
| 477 | // f(int(v)) is valid; int(v) has no defined methods. |
| 478 | </pre> |
| 479 | |
| 480 | <p> |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 481 | Given this interface: |
| 482 | |
| 483 | <pre> |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 484 | type myInterface interface { |
Ian Lance Taylor | bf57520 | 2010-01-29 16:37:50 -0800 | [diff] [blame] | 485 | get() int |
| 486 | set(i int) |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 487 | } |
| 488 | </pre> |
| 489 | |
| 490 | <p> |
Russ Cox | 2a63f5d | 2009-11-08 01:08:26 -0800 | [diff] [blame] | 491 | we can make <code>myType</code> satisfy the interface by adding |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 492 | |
| 493 | <pre> |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 494 | func (p *myType) set(i int) { p.i = i } |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 495 | </pre> |
| 496 | |
| 497 | <p> |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 498 | Now any function which takes <code>myInterface</code> as a parameter |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 499 | will accept a |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 500 | variable of type <code>*myType</code>. |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 501 | |
| 502 | <pre> |
Rob Pike | 6ac19ec | 2009-11-01 20:57:13 -0800 | [diff] [blame] | 503 | func getAndSet(x myInterface) {} |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 504 | func f1() { |
Ian Lance Taylor | bf57520 | 2010-01-29 16:37:50 -0800 | [diff] [blame] | 505 | var p myType |
| 506 | getAndSet(&p) |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 507 | } |
| 508 | </pre> |
| 509 | |
| 510 | <p> |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 511 | In other words, if we view <code>myInterface</code> as a C++ pure abstract |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 512 | base |
| 513 | class, defining <code>set</code> and <code>get</code> for |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 514 | <code>*myType</code> made <code>*myType</code> automatically |
| 515 | inherit from <code>myInterface</code>. A type may satisfy multiple interfaces. |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 516 | |
| 517 | <p> |
| 518 | An anonymous field may be used to implement something much like a C++ child |
| 519 | class. |
| 520 | |
| 521 | <pre> |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 522 | type myChildType struct { myType; j int } |
Russ Cox | 2a63f5d | 2009-11-08 01:08:26 -0800 | [diff] [blame] | 523 | func (p *myChildType) get() int { p.j++; return p.myType.get() } |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 524 | </pre> |
| 525 | |
| 526 | <p> |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 527 | This effectively implements <code>myChildType</code> as a child of |
| 528 | <code>myType</code>. |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 529 | |
| 530 | <pre> |
| 531 | func f2() { |
Ian Lance Taylor | bf57520 | 2010-01-29 16:37:50 -0800 | [diff] [blame] | 532 | var p myChildType |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 533 | getAndSet(&p) |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 534 | } |
| 535 | </pre> |
| 536 | |
| 537 | <p> |
| 538 | The <code>set</code> method is effectively inherited from |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 539 | <code>myChildType</code>, because |
Russ Cox | 2a63f5d | 2009-11-08 01:08:26 -0800 | [diff] [blame] | 540 | methods associated with the anonymous field are promoted to become methods |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 541 | of the enclosing type. In this case, because <code>myChildType</code> has an |
| 542 | anonymous field of type <code>myType</code>, the methods of |
| 543 | <code>myType</code> also become methods of <code>myChildType</code>. |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 544 | In this example, the <code>get</code> method was |
| 545 | overridden, and the <code>set</code> method was inherited. |
| 546 | |
| 547 | <p> |
Russ Cox | 2a63f5d | 2009-11-08 01:08:26 -0800 | [diff] [blame] | 548 | This is not precisely the same as a child class in C++. |
| 549 | When a method of an anonymous field is called, |
| 550 | its receiver is the field, not the surrounding struct. |
| 551 | In other words, methods on anonymous fields are not virtual functions. |
| 552 | When you want the equivalent of a virtual function, use an interface. |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 553 | |
| 554 | <p> |
| 555 | A variable which has an interface type may be converted to have a |
Rob Pike | 6ac19ec | 2009-11-01 20:57:13 -0800 | [diff] [blame] | 556 | different interface type using a special construct called a type assertion. |
| 557 | This is implemented dynamically |
Rob Pike | 966bf71 | 2011-03-01 13:54:22 -0800 | [diff] [blame] | 558 | at run time, like C++ <code>dynamic_cast</code>. Unlike |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 559 | <code>dynamic_cast</code>, there does |
| 560 | not need to be any declared relationship between the two interfaces. |
| 561 | |
| 562 | <pre> |
Rob Pike | 6ac19ec | 2009-11-01 20:57:13 -0800 | [diff] [blame] | 563 | type myPrintInterface interface { |
Ian Lance Taylor | bf57520 | 2010-01-29 16:37:50 -0800 | [diff] [blame] | 564 | print() |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 565 | } |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 566 | func f3(x myInterface) { |
Rob Pike | 6ac19ec | 2009-11-01 20:57:13 -0800 | [diff] [blame] | 567 | x.(myPrintInterface).print() // type assertion to myPrintInterface |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 568 | } |
| 569 | </pre> |
| 570 | |
| 571 | <p> |
Rob Pike | 6ac19ec | 2009-11-01 20:57:13 -0800 | [diff] [blame] | 572 | The conversion to <code>myPrintInterface</code> is entirely dynamic. |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 573 | It will |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 574 | work as long as the underlying type of x (the <em>dynamic type</em>) defines |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 575 | a <code>print</code> method. |
| 576 | |
| 577 | <p> |
| 578 | Because the conversion is dynamic, it may be used to implement generic |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 579 | programming similar to templates in C++. This is done by |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 580 | manipulating values of the minimal interface. |
| 581 | |
| 582 | <pre> |
| 583 | type Any interface { } |
| 584 | </pre> |
| 585 | |
| 586 | <p> |
Rob Pike | 6ac19ec | 2009-11-01 20:57:13 -0800 | [diff] [blame] | 587 | Containers may be written in terms of <code>Any</code>, but the caller |
| 588 | must unbox using a type assertion to recover |
| 589 | values of the contained type. As the typing is dynamic rather |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 590 | than static, there is no equivalent of the way that a C++ template may |
| 591 | inline the relevant operations. The operations are fully type-checked |
Rob Pike | 966bf71 | 2011-03-01 13:54:22 -0800 | [diff] [blame] | 592 | at run time, but all operations will involve a function call. |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 593 | |
| 594 | <pre> |
| 595 | type iterator interface { |
Ian Lance Taylor | bf57520 | 2010-01-29 16:37:50 -0800 | [diff] [blame] | 596 | get() Any |
| 597 | set(v Any) |
| 598 | increment() |
| 599 | equal(arg *iterator) bool |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 600 | } |
| 601 | </pre> |
| 602 | |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 603 | <h2 id="Goroutines">Goroutines</h2> |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 604 | |
| 605 | <p> |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 606 | Go permits starting a new thread of execution (a <em>goroutine</em>) |
| 607 | using the <code>go</code> |
| 608 | statement. The <code>go</code> statement runs a function in a |
| 609 | different, newly created, goroutine. |
| 610 | All goroutines in a single program share the same address space. |
| 611 | |
| 612 | <p> |
| 613 | Internally, goroutines act like coroutines that are multiplexed among |
| 614 | multiple operating system threads. You do not have to worry |
| 615 | about these details. |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 616 | |
| 617 | <pre> |
Russ Cox | 2a63f5d | 2009-11-08 01:08:26 -0800 | [diff] [blame] | 618 | func server(i int) { |
| 619 | for { |
Ian Lance Taylor | bf57520 | 2010-01-29 16:37:50 -0800 | [diff] [blame] | 620 | print(i) |
Russ Cox | 2a63f5d | 2009-11-08 01:08:26 -0800 | [diff] [blame] | 621 | sys.sleep(10) |
| 622 | } |
| 623 | } |
Ian Lance Taylor | bf57520 | 2010-01-29 16:37:50 -0800 | [diff] [blame] | 624 | go server(1) |
| 625 | go server(2) |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 626 | </pre> |
| 627 | |
| 628 | <p> |
| 629 | (Note that the <code>for</code> statement in the <code>server</code> |
Rob Pike | 6ac19ec | 2009-11-01 20:57:13 -0800 | [diff] [blame] | 630 | function is equivalent to a C++ <code>while (true)</code> loop.) |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 631 | |
| 632 | <p> |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 633 | Goroutines are (intended to be) cheap. |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 634 | |
| 635 | <p> |
Rob Pike | 6ac19ec | 2009-11-01 20:57:13 -0800 | [diff] [blame] | 636 | Function literals (which Go implements as closures) |
| 637 | can be useful with the <code>go</code> statement. |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 638 | |
| 639 | <pre> |
Ian Lance Taylor | bf57520 | 2010-01-29 16:37:50 -0800 | [diff] [blame] | 640 | var g int |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 641 | go func(i int) { |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 642 | s := 0 |
| 643 | for j := 0; j < i; j++ { s += j } |
Ian Lance Taylor | bf57520 | 2010-01-29 16:37:50 -0800 | [diff] [blame] | 644 | g = s |
| 645 | }(1000) // Passes argument 1000 to the function literal. |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 646 | </pre> |
| 647 | |
| 648 | <h2 id="Channels">Channels</h2> |
| 649 | |
| 650 | <p> |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 651 | Channels are used to communicate between goroutines. Any value may be |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 652 | sent over a channel. Channels are (intended to be) efficient and |
| 653 | cheap. To send a value on a channel, use <code><-</code> as a binary |
| 654 | operator. To |
| 655 | receive a value on a channel, use <code><-</code> as a unary operator. |
| 656 | When calling |
| 657 | functions, channels are passed by reference. |
| 658 | |
| 659 | <p> |
| 660 | The Go library provides mutexes, but you can also use |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 661 | a single goroutine with a shared channel. |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 662 | Here is an example of using a manager function to control access to a |
| 663 | single value. |
| 664 | |
| 665 | <pre> |
| 666 | type cmd struct { get bool; val int } |
| 667 | func manager(ch chan cmd) { |
Ian Lance Taylor | bf57520 | 2010-01-29 16:37:50 -0800 | [diff] [blame] | 668 | var val int = 0 |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 669 | for { |
| 670 | c := <- ch |
Andrew Gerrand | 7757fcc | 2010-09-17 12:39:01 +1000 | [diff] [blame] | 671 | if c.get { c.val = val; ch <- c } |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 672 | else { val = c.val } |
| 673 | } |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 674 | } |
| 675 | </pre> |
| 676 | |
| 677 | <p> |
Russ Cox | 2a63f5d | 2009-11-08 01:08:26 -0800 | [diff] [blame] | 678 | In that example the same channel is used for input and output. |
| 679 | This is incorrect if there are multiple goroutines communicating |
| 680 | with the manager at once: a goroutine waiting for a response |
| 681 | from the manager might receive a request from another goroutine |
| 682 | instead. |
| 683 | A solution is to pass in a channel. |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 684 | |
| 685 | <pre> |
Ian Lance Taylor | bf57520 | 2010-01-29 16:37:50 -0800 | [diff] [blame] | 686 | type cmd2 struct { get bool; val int; ch <- chan int } |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 687 | func manager2(ch chan cmd2) { |
Ian Lance Taylor | bf57520 | 2010-01-29 16:37:50 -0800 | [diff] [blame] | 688 | var val int = 0 |
Ian Lance Taylor | e285487 | 2009-10-12 15:43:13 -0700 | [diff] [blame] | 689 | for { |
| 690 | c := <- ch |
| 691 | if c.get { c.ch <- val } |
| 692 | else { val = c.val } |
| 693 | } |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 694 | } |
| 695 | </pre> |
| 696 | |
| 697 | <p> |
Rob Pike | 6ac19ec | 2009-11-01 20:57:13 -0800 | [diff] [blame] | 698 | To use <code>manager2</code>, given a channel to it: |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 699 | |
| 700 | <pre> |
| 701 | func f4(ch <- chan cmd2) int { |
Ian Lance Taylor | bf57520 | 2010-01-29 16:37:50 -0800 | [diff] [blame] | 702 | myCh := make(chan int) |
| 703 | c := cmd2{ true, 0, myCh } // Composite literal syntax. |
| 704 | ch <- c |
| 705 | return <-myCh |
Larry Hosken | 698c6c0 | 2009-09-17 08:05:12 -0700 | [diff] [blame] | 706 | } |
| 707 | </pre> |