blob: dd8af5f40bb59d2584e25f8171a499afe8b4e0e4 [file] [log] [blame] [view]
Andrew Gerrand5bc444d2014-12-10 11:35:11 +11001Go is a systems programming language intended to be a general-purpose systems
2language, like C++. These are some notes on Go for experienced C++
3programmers. This document discusses the differences between Go and C++, and
4says little to nothing about the similarities.
5
6An important point to keep in mind is that there are some fundamental differences in the thought processes required to be proficient in the two respective languages. Most formidably, C++'s object model is based on classes and class hierarchies while Go's object model is based on interfaces (and is essentially flat). Consequently, C++ design patterns rarely translate verbatim to Go. To program effectively in Go, one has to consider the _problem_ being solved, not the mechanisms one might use in C++ to solve the problem.
7
8For a more general introduction to Go, see the
9<a href='http://tour.golang.org/'>Go Tour</a>,
10<a href='http://golang.org/doc/code.html'>How to Write Go Code</a>
11and <a href='http://golang.org/doc/effective_go.html'>Effective Go</a>.
12
13For a detailed description of the Go language, see the
14<a href='http://golang.org/doc/go_spec.html'>Go spec</a>.
15
16<h2>Conceptual Differences</h2>
17
18<ul>
19<li>Go does not have classes with constructors or destructors. Instead of<br>
20class methods, a class inheritance hierarchy, and virtual functions, Go<br>
21provides <em>interfaces</em>, which are discussed in more detail below.<br>
22Interfaces are also used where C++ uses templates.</li>
23
24<li>Go provides automatic garbage collection of allocated memory. It is not necessary (or possible) to release memory explicitly. There is no need to worry about heap-allocated vs. stack-allocated storage, <code>new</code> vs. <code>malloc</code>, or <code>delete</code> vs. <code>delete[]</code> vs. <code>free</code>. There is no need to separately manage <code>std::unique_ptr</code>, <code>std::shared_ptr</code>, <code>std::weak_ptr</code>, <code>std::auto_ptr</code>, and ordinary, "dumb" pointers. Go's run-time system handles all of that error-prone code on the programmer's behalf.</li>
25
26<li>Go has pointers but not pointer arithmetic. Go pointers therefore more closely resemble C++ references. One cannot use a Go pointer<br>
27variable to walk through the bytes of a string, for example. Slices, discussed further below, satisfy most of the need for pointer arithmetic.</li>
28
29<li>Go is "safe" by default. Pointers cannot point to arbitrary memory, and buffer overruns result in crashes, not security exploits. The <code>unsafe</code> package lets programmers bypass some of Go's protection mechanisms where explicitly requested.</li>
30
31<li>Arrays in Go are first class values. When an array is used as a function<br>
32parameter, the function receives a copy of the array, not a pointer to it.<br>
33However, in practice functions often use slices for parameters; slices hold<br>
34pointers to underlying arrays. Slices are discussed further below.</li>
35
36<li>Strings are provided by the language. They may not be changed once they<br>
37have been created.</li>
38
39<li>Hash tables are provided by the language. They are called maps.</li>
40
41<li>Separate threads of execution, and communication channels between them, are<br>
42provided by the language. This is discussed further below.</li>
43
44<li>Certain types (maps and channels, described further below) are passed by<br>
45reference, not by value. That is, passing a map to a function does not copy the<br>
46map, and if the function changes the map the change will be seen by the caller.<br>
47In C++ terms, one can think of these as being reference types.</li>
48
49<li>Go does not use header files. Instead, each source file is part of a<br>
50defined <em>package</em>. When a package defines an object (type, constant,<br>
51variable, function) with a name starting with an upper case letter, that object<br>
52is visible to any other file which imports that package.</li>
53
54<li>Go does not support implicit type conversion. Operations that mix different types require casts (called conversions in Go). This is true even of different user-defined aliases of the same underlying type.</li>
55
56<li>Go does not support function overloading and does not support user defined<br>
57operators.</li>
58
59<li>Go does not support <code>const</code> or <code>volatile</code> qualifiers.</li>
60
61<li>Go uses <code>nil</code> for invalid pointers, where C++ uses <code>NULL</code> or simply <code>0</code> (or in C++11, <code>nullptr</code>).</li>
62
63<li>Idiomatic Go uses multiple return values to convey errors—one or more data results plus an error code—instead of sentinel values (e.g., <code>-1</code>) or structured exception handling (C++'s <code>try</code>…<code>catch</code> and <code>throw</code> or Go's <code>panic</code>…<code>recover</code>).</li>
64
65</ul>
66
67<h2>Syntax</h2>
68
69The declaration syntax is reversed compared to C++. You write the name
70followed by the type. Unlike in C++, the syntax for a type does not match
71the way in which the variable is used. Type declarations may be read
72easily from left to right. (` var v1 int ` → "Variable ` v1 ` is an ` int `.")
73
ratchetfreak24688932016-10-27 18:02:14 +020074```go
75//Go C++
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110076var v1 int // int v1;
77var v2 string // const std::string v2; (approximately)
78var v3 [10]int // int v3[10];
79var v4 []int // int* v4; (approximately)
80var v5 struct { f int } // struct { int f; } v5;
81var v6 *int // int* v6; (but no pointer arithmetic)
82var v7 map[string]int // unordered_map<string, int>* v7; (approximately)
83var v8 func(a int) int // int (*v8)(int a);
84```
85
86Declarations generally take the form of a keyword followed by the name
87of the object being declared. The keyword is one of ` var `,
88` func `,
89` const `, or ` type `. Method declarations are a minor
90exception in that
91the receiver appears before the name of the object being declared; see
92the <a href='#Interfaces'>discussion of interfaces</a>.
93
94You can also use a keyword followed by a series of declarations in
95parentheses.
96
ratchetfreak24688932016-10-27 18:02:14 +020097```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110098var (
Dave Day0d6986a2014-12-10 15:02:18 +110099 i int
100 m float64
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100101)
102```
103
104When declaring a function, you must either provide a name for each parameter
105or not provide a name for any parameter. (That is, C++ permits ` void f(int i, int); `, but Go does not permit the analogous ` func f(i int, int) `.) However, for convenience, in Go you may group several names with the same type:
106
ratchetfreak24688932016-10-27 18:02:14 +0200107```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100108func f(i, j, k int, s, t string)
109```
110
111A variable may be initialized when it is declared. When this is done,
112specifying the type is permitted but not required. When the type is
113not specified, the type of the variable is the type of the
114initialization expression.
115
ratchetfreak24688932016-10-27 18:02:14 +0200116```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100117var v = *p
118```
119
120See also the <a href='#Constants'>discussion of constants, below</a>.
121If a variable is not initialized explicitly, the type must be specified.
122In that case it will be
123implicitly initialized to the type's zero value
124(` 0 `, ` nil `, etc.). There are no
125uninitialized variables in Go.
126
127Within a function, a short declaration syntax is available with
128` := ` .
129
ratchetfreak24688932016-10-27 18:02:14 +0200130```go
Dave Day0d6986a2014-12-10 15:02:18 +1100131v1 := v2 // C++11: auto v1 = v2;
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100132```
133
134This is equivalent to
135
ratchetfreak24688932016-10-27 18:02:14 +0200136```go
Dave Day0d6986a2014-12-10 15:02:18 +1100137var v1 = v2 // C++11: auto v1 = v2;
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100138```
139
140Go permits multiple assignments, which are done in parallel. That is, first all of the values on the right-hand side are computed, and then these values are assigned to the variables on the left-hand side.
141
ratchetfreak24688932016-10-27 18:02:14 +0200142```go
Dave Day0d6986a2014-12-10 15:02:18 +1100143i, j = j, i // Swap i and j.
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100144```
145
146Functions may have multiple return values, indicated by a list in
147parentheses. The returned values can be stored by assignment
148to a list of variables.
149
ratchetfreak24688932016-10-27 18:02:14 +0200150```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100151func f() (i int, j int) { ... }
152v1, v2 = f()
153```
154
155Multiple return values are Go's primary mechanism for error handling:
156
ratchetfreak24688932016-10-27 18:02:14 +0200157```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100158result, ok := g()
159if !ok {
160 // Something bad happened.
161 return nil
162}
163// Continue as normal.
164
165```
166
167or, more tersely,
168
ratchetfreak24688932016-10-27 18:02:14 +0200169```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100170if result, ok := g(); !ok {
171 // Something bad happened.
172 return nil
173}
174// Continue as normal.
175
176```
177
178Go code uses very few semicolons in practice. Technically, all Go
179statements are terminated by a semicolon. However, Go treats the end
180of a non-blank line as a semicolon unless the line is clearly
181incomplete (the exact rules are
Andrey Tkachenkoe3c10592015-12-07 17:53:52 +0100182in <a href='https://golang.org/ref/spec#Semicolons'>the language specification</a>).
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100183A consequence of this is that in some cases Go does not permit you to
184use a line break. For example, you may not write
ratchetfreak24688932016-10-27 18:02:14 +0200185```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100186func g()
187{ // INVALID
188}
189```
190A semicolon will be inserted after ` g() `, causing it to be
191a function declaration rather than a function definition. Similarly,
192you may not write
ratchetfreak24688932016-10-27 18:02:14 +0200193```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100194if x {
195}
196else { // INVALID
197}
198```
199A semicolon will be inserted after the ` } ` preceding
200the ` else `, causing a syntax error.
201
202Since semicolons do end statements, you may continue using them as in
203C++. However, that is not the recommended style. Idiomatic Go code
204omits unnecessary semicolons, which in practice is all of them other
205than the initial ` for ` loop clause and cases where you want several
206short statements on a single line.
207
208While we're on the topic, we recommend that rather than worry about
209semicolons and brace placement, you format your code with
210the ` gofmt ` program. That will produce a single standard
211Go style, and let you worry about your code rather than your
212formatting. While the style may initially seem odd, it is as good as
213any other style, and familiarity will lead to comfort.
214
215When using a pointer to a struct, you use ` . ` instead
216of ` -> `.
217Thus, syntactically speaking, a structure and a pointer to a structure
218are used in the same way.
219
ratchetfreak24688932016-10-27 18:02:14 +0200220```go
Dave Day0d6986a2014-12-10 15:02:18 +1100221type myStruct struct{ i int }
222var v9 myStruct // v9 has structure type
223var p9 *myStruct // p9 is a pointer to a structure
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100224f(v9.i, p9.i)
225```
226
227Go does not require parentheses around the condition of an ` if `
228statement, or the expressions of a ` for ` statement, or the value of a
229` switch ` statement. On the other hand, it does require curly braces
230around the body of an ` if ` or ` for ` statement.
231
ratchetfreak24688932016-10-27 18:02:14 +0200232```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100233if a < b { f() } // Valid
234if (a < b) { f() } // Valid (condition is a parenthesized expression)
235if (a < b) f() // INVALID
236for i = 0; i < 10; i++ {} // Valid
237for (i = 0; i < 10; i++) {} // INVALID
238```
239
240Go does not have a ` while ` statement nor does it have a
241` do/while `
242statement. The ` for ` statement may be used with a single condition,
243which makes it equivalent to a ` while ` statement. Omitting the
244condition entirely is an endless loop.
245
246Go permits ` break ` and ` continue ` to specify a label.
247The label must
248refer to a ` for `, ` switch `, or ` select `
249statement.
250
251In a ` switch ` statement, ` case ` labels do not fall
252through. You can
253make them fall through using the ` fallthrough ` keyword. This applies
254even to adjacent cases.
255
ratchetfreak24688932016-10-27 18:02:14 +0200256```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100257switch i {
Dave Day0d6986a2014-12-10 15:02:18 +1100258case 0: // empty case body
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100259case 1:
Dave Day0d6986a2014-12-10 15:02:18 +1100260 f() // f is not called when i == 0!
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100261}
262```
263
264But a ` case ` can have multiple values.
265
ratchetfreak24688932016-10-27 18:02:14 +0200266```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100267switch i {
268case 0, 1:
Dave Day0d6986a2014-12-10 15:02:18 +1100269 f() // f is called if i == 0 || i == 1.
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100270}
271```
272
273The values in a ` case ` need not be constants--or even integers;
274any type
275that supports the equality comparison operator, such as strings or
276pointers, can be used--and if the ` switch `
277value is omitted it defaults to ` true `.
278
ratchetfreak24688932016-10-27 18:02:14 +0200279```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100280switch {
281case i < 0:
Dave Day0d6986a2014-12-10 15:02:18 +1100282 f1()
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100283case i == 0:
Dave Day0d6986a2014-12-10 15:02:18 +1100284 f2()
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100285case i > 0:
Dave Day0d6986a2014-12-10 15:02:18 +1100286 f3()
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100287}
288```
289
290The ` defer ` statement may be used to call a function after the function containing the ` defer ` statement returns. ` defer ` often takes the place of a destructor in C++ but is associated with the calling code, not any particular class or object.
291
ratchetfreak24688932016-10-27 18:02:14 +0200292```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100293fd := open("filename")
Dave Day0d6986a2014-12-10 15:02:18 +1100294defer close(fd) // fd will be closed when this function returns.
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100295```
296
297<h2>Operators</h2>
298
299The ` ++ ` and ` -- ` operators may only be used in
300statements, not in expressions.
301You cannot write ` c = *p++ `. ` *p++ ` is parsed as
302` (*p)++ `.
303
304The operator precedence is different. As an example ` 4 & 3 << 1 ` evaluates to ` 0 ` in Go and ` 4 ` in C++.
305```
306Go operator precedence:
3071. * / % << >> & &^
3082. + - | ^
3093. == != < <= > >=
3104. &&
3115. ||
312```
313
314```
315C++ operator precedence (only relevant operators):
3161. * / %
3172. + -
3183. << >>
3194. < <= > >=
3205. == !=
3216. &
3227. ^
3238. |
3249. &&
32510. ||
326```
327
328
329<h2>Constants </h2>
330
331In Go constants may be <i>untyped</i>. This applies even to constants
332named with a ` const ` declaration, if no
333type is given in the declaration and the initializer expression uses only
334untyped constants.
335A value derived from an untyped constant becomes typed when it
336is used within a context that
337requires a typed value. This permits constants to be used relatively
338freely without requiring general implicit type conversion.
339
ratchetfreak24688932016-10-27 18:02:14 +0200340```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100341var a uint
Dave Day0d6986a2014-12-10 15:02:18 +1100342f(a + 1) // untyped numeric constant "1" becomes typed as uint
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100343```
344
345The language does not impose any limits on the size of an untyped
346numeric constant or constant expression. A limit is only applied when
347a constant is used where a type is required.
348
ratchetfreak24688932016-10-27 18:02:14 +0200349```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100350const huge = 1 << 100
351f(huge >> 98)
352```
353
354Go does not support enums. Instead, you can use the special name
355` iota ` in a single ` const ` declaration to get a
356series of increasing
357value. When an initialization expression is omitted for a ` const `,
358it reuses the preceding expression.
359
ratchetfreak24688932016-10-27 18:02:14 +0200360```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100361const (
Dave Day0d6986a2014-12-10 15:02:18 +1100362 red = iota // red == 0
363 blue // blue == 1
364 green // green == 2
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100365)
366```
367
368<h2>Types</h2>
369
370C++ and Go provide similar, but not identical, built-in types: signed and unsigned integers of various widths, 32-bit and 64-bit floating-point numbers (real and complex), ` struct `s, pointers, etc. In Go, ` uint8 `, ` int64 `, and like-named integer types are part of the language, not built on top of integers whose sizes are implementation-dependent (e.g., ` long long `). Go additionally provides native ` string `, ` map `, and ` channel ` types as well as first-class arrays and slices (described below). Strings are encoded with Unicode, not ASCII.
371
372Go is far more strongly typed than C++. In particular, there is no implicit type coercion in Go, only explicit type conversion. This provides additional safety and freedom from a class of bugs but at the cost of some additional typing. There is also no ` union ` type in Go, as this would enable subversion of the type system. However, a Go ` interface{} ` (see below) provides a type-safe alternative.
373
374Both C++ and Go support type aliases (` typedef ` in C++, ` type ` in Go). However, unlike C++, Go treats these as different types. Hence, the following is valid in C++:
375
ratchetfreak24688932016-10-27 18:02:14 +0200376```C++
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100377// C++
378typedef double position;
379typedef double velocity;
380
381position pos = 218.0;
382velocity vel = -9.8;
383
384pos += vel;
385```
386
387but the equivalent is invalid in Go without an explicit type conversion:
388
ratchetfreak24688932016-10-27 18:02:14 +0200389```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100390type position float64
391type velocity float64
392
393var pos position = 218.0
394var vel velocity = -9.8
395
Dave Day0d6986a2014-12-10 15:02:18 +1100396pos += vel // INVALID: mismatched types position and velocity
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100397// pos += position(vel) // Valid
398```
399
400The same is true even for unaliased types: an ` int ` and a ` uint ` cannot be combined in an expression without explicitly converting one to the other.
401
402Go does not allow pointers to be cast to and from integers, unlike in C++. However, Go's ` unsafe ` package enables one to explicitly bypass this safety mechanism if necessary (e.g., for use in low-level systems code).
403
404
405<h2>Slices</h2>
406
407A slice is conceptually a struct with three fields: a
408pointer to an array, a length, and a capacity.
409Slices support
410the ` [] ` operator to access elements of the underlying array.
411The builtin
412` len ` function returns the
413length of the slice. The builtin ` cap ` function returns the
414capacity.
415
416Given an array, or another slice, a new slice is created via
417` a[i:j] `. This
418creates a new slice which refers to ` a `, starts at
419index ` i `, and ends before index
420` j `. It has length ` j-i `.
421If ` i ` is omitted, the slice starts at ` 0 `.
422If ` j ` is omitted, the slice ends at ` len(a) `.
423The new slice refers to the same array
424to which ` a `
425refers. Two implications of this statement are that ① changes made using the new slice may be seen using
426` a `, and ② slice creation is (intended to be) cheap; no copy needs to be made of the underlying array. The
427capacity of the new slice is simply the capacity of ` a ` minus
428` i `. The capacity
429of an array is the length of the array.
430
431What this means is that Go uses slices for some cases where C++ uses pointers.
432If you create a value of type ` [100]byte ` (an array of 100 bytes,
433perhaps a
434buffer) and you want to pass it to a function without copying it, you should
435declare the function parameter to have type ` []byte `, and
436pass a slice of the array (` a[:] ` will pass the entire array).
437Unlike in C++, it is not
438necessary to pass the length of the buffer; it is efficiently accessible via
439` len `.
440
441The slice syntax may also be used with a string. It returns a new string,
442whose value is a substring of the original string.
443Because strings are immutable, string slices can be implemented
444without allocating new storage for the slices's contents.
445
446<h2>Making values</h2>
447
448Go has a builtin function ` new ` which takes a type and
449allocates space
450on the heap. The allocated space will be zero-initialized for the type.
451For example, ` new(int) ` allocates a new int on the heap,
452initializes it with the value ` 0 `,
453and returns its address, which has type ` *int `.
454Unlike in C++, ` new ` is a function, not an operator;
455` new int ` is a syntax error.
456
457Perhaps surprisingly, ` new ` is not commonly used in Go
458programs. In Go taking the address of a variable is always safe and
459never yields a dangling pointer. If the program takes the address of
460a variable, it will be allocated on the heap if necessary. So these
461functions are equivalent:
462
ratchetfreak24688932016-10-27 18:02:14 +0200463```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100464type S { I int }
465
466func f1() *S {
467 return new(S)
468}
469
470func f2() *S {
471 var s S
472 return &s
473}
474
475func f3() *S {
476 // More idiomatic: use composite literal syntax.
477 return &S{}
478}
479```
480
481In contrast, it is not safe in C++ to return a pointer to a local variable:
482
ratchetfreak24688932016-10-27 18:02:14 +0200483```C++
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100484// C++
485S* f2() {
486 S s;
487 return &s; // INVALID -- contents can be overwritten at any time
488}
489```
490
491Map and channel values must be allocated using the builtin function
492` make `.
493A variable declared with map or channel type without an initializer will be
494automatically initialized to ` nil `.
495Calling ` make(map[int]int) ` returns a newly allocated value of
496type ` map[int]int `.
497Note that ` make ` returns a value, not a pointer. This is
498consistent with
499the fact that map and channel values are passed by reference. Calling
500` make ` with
501a map type takes an optional argument which is the expected capacity of the
502map. Calling ` make ` with a channel type takes an optional
503argument which sets the
504buffering capacity of the channel; the default is 0 (unbuffered).
505
506The ` make ` function may also be used to allocate a slice.
507In this case it
508allocates memory for the underlying array and returns a slice referring to it.
509There is one required argument, which is the number of elements in the slice.
510A second, optional, argument is the capacity of the slice. For example,
511` make([]int, 10, 20) `. This is identical to
512` new([20]int)[0:10] `. Since
513Go uses garbage collection, the newly allocated array will be discarded
514sometime after there are no references to the returned slice.
515
516<h2>Interfaces</h2>
517
518Where C++ provides classes, subclasses and templates,
519Go provides interfaces. A
520Go interface is similar to a C++ pure abstract class: a class with no
521data members, with methods which are all pure virtual. However, in
522Go, any type which provides the methods named in the interface may be
523treated as an implementation of the interface. No explicitly declared
524inheritance is required. The implementation of the interface is
525entirely separate from the interface itself.
526
527A method looks like an ordinary function definition, except that it
528has a <em>receiver</em>. The receiver is similar to
529the ` this ` pointer in a C++ class method.
530
ratchetfreak24688932016-10-27 18:02:14 +0200531```go
Dave Day0d6986a2014-12-10 15:02:18 +1100532type myType struct{ i int }
533
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100534func (p *myType) Get() int { return p.i }
535```
536
537This declares a method ` Get ` associated with ` myType `.
538The receiver is named ` p ` in the body of the function.
539
540Methods are defined on named types. If you convert the value
541to a different type, the new value will have the methods of the new type,
542not the old type.
543
544You may define methods on a builtin type by declaring a new named type
545derived from it. The new type is distinct from the builtin type.
546
ratchetfreak24688932016-10-27 18:02:14 +0200547```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100548type myInteger int
Dave Day0d6986a2014-12-10 15:02:18 +1100549
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100550func (p myInteger) Get() int { return int(p) } // Conversion required.
Dave Day0d6986a2014-12-10 15:02:18 +1100551func f(i int) {}
552
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100553var v myInteger
Dave Day0d6986a2014-12-10 15:02:18 +1100554
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100555// f(v) is invalid.
556// f(int(v)) is valid; int(v) has no defined methods.
557```
558
559Given this interface:
560
ratchetfreak24688932016-10-27 18:02:14 +0200561```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100562type myInterface interface {
563 Get() int
564 Set(i int)
565}
566```
567
568we can make ` myType ` satisfy the interface by adding
569
ratchetfreak24688932016-10-27 18:02:14 +0200570```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100571func (p *myType) Set(i int) { p.i = i }
572```
573
574Now any function which takes ` myInterface ` as a parameter
575will accept a
576variable of type ` *myType `.
577
ratchetfreak24688932016-10-27 18:02:14 +0200578```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100579func GetAndSet(x myInterface) {}
580func f1() {
581 var p myType
582 GetAndSet(&p)
583}
584```
585
586In other words, if we view ` myInterface ` as a C++ pure abstract
587base
588class, defining ` Set ` and ` Get ` for
589` *myType ` made ` *myType ` automatically
590inherit from ` myInterface `. A type may satisfy multiple interfaces.
591
592An anonymous field may be used to implement something much like a C++ child
593class.
594
ratchetfreak24688932016-10-27 18:02:14 +0200595```go
Dave Day0d6986a2014-12-10 15:02:18 +1100596type myChildType struct {
597 myType
598 j int
599}
600
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100601func (p *myChildType) Get() int { p.j++; return p.myType.Get() }
602```
603
604This effectively implements ` myChildType ` as a child of
605` myType `.
606
ratchetfreak24688932016-10-27 18:02:14 +0200607```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100608func f2() {
609 var p myChildType
610 GetAndSet(&p)
611}
612```
613
614The ` set ` method is effectively inherited from
615` myType `, because
616methods associated with the anonymous field are promoted to become methods
617of the enclosing type. In this case, because ` myChildType ` has an
618anonymous field of type ` myType `, the methods of
619` myType ` also become methods of ` myChildType `.
620In this example, the ` Get ` method was
621overridden, and the ` Set ` method was inherited.
622
623This is not precisely the same as a child class in C++.
624When a method of an anonymous field is called,
625its receiver is the field, not the surrounding struct.
626In other words, methods on anonymous fields are not virtual functions.
627When you want the equivalent of a virtual function, use an interface.
628
629A variable that has an interface type may be converted to have a
630different interface type using a special construct called a type assertion.
631This is implemented dynamically
632at run time, like C++ ` dynamic_cast `. Unlike
633` dynamic_cast `, there does
634not need to be any declared relationship between the two interfaces.
635
ratchetfreak24688932016-10-27 18:02:14 +0200636```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100637type myPrintInterface interface {
638 Print()
639}
Dave Day0d6986a2014-12-10 15:02:18 +1100640
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100641func f3(x myInterface) {
Dave Day0d6986a2014-12-10 15:02:18 +1100642 x.(myPrintInterface).Print() // type assertion to myPrintInterface
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100643}
644```
645
646The conversion to ` myPrintInterface ` is entirely dynamic.
647It will
648work as long as the underlying type of x (the <em>dynamic type</em>) defines
649a ` print ` method.
650
651Because the conversion is dynamic, it may be used to implement generic
652programming similar to templates in C++. This is done by
653manipulating values of the minimal interface.
654
ratchetfreak24688932016-10-27 18:02:14 +0200655```go
Dave Day0d6986a2014-12-10 15:02:18 +1100656type Any interface{}
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100657```
658
659Containers may be written in terms of ` Any `, but the caller
660must unbox using a type assertion to recover
661values of the contained type. As the typing is dynamic rather
662than static, there is no equivalent of the way that a C++ template may
663inline the relevant operations. The operations are fully type-checked
664at run time, but all operations will involve a function call.
665
ratchetfreak24688932016-10-27 18:02:14 +0200666```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100667type Iterator interface {
668 Get() Any
669 Set(v Any)
670 Increment()
671 Equal(arg Iterator) bool
672}
673```
674
675Note that ` Equal ` has an argument of
676type ` Iterator `. This does not behave like a C++
677template. See <a href='go_faq.html#t_and_equal_interface'>the<br>
678FAQ</a>.
679
680<h2>Function closures</h2>
681
682In C++ versions prior to C++11, the most common way to create a function with hidden state is to use a "functor"—a class that overloads ` operator() ` to make instances look like functions. For example, the following code defines a ` my_transform ` function (a simplified version of the STL's ` std::transform `) that applies a given unary operator (` op `) to each element of an array (` in `), storing the result in another array (` out `). To implement a prefix sum (i.e., {` x[0] `, ` x[0]+x[1] `, ` x[0]+x[1]+x[2] `, …}) the code creates a functor (` MyFunctor `) that keeps track of the running total (` total `) and passes an instance of this functor to ` my_transform `.
683
ratchetfreak24688932016-10-27 18:02:14 +0200684```C++
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100685// C++
686#include <iostream>
687#include <cstddef>
688
689template <class UnaryOperator>
690void my_transform (size_t n_elts, int* in, int* out, UnaryOperator op)
691{
692 size_t i;
693
694 for (i = 0; i < n_elts; i++)
695 out[i] = op(in[i]);
696}
697
698class MyFunctor {
699public:
700 int total;
701 int operator()(int v) {
702 total += v;
703 return total;
704 }
705 MyFunctor() : total(0) {}
706};
707
708int main (void)
709{
710 int data[7] = {8, 6, 7, 5, 3, 0, 9};
711 int result[7];
712 MyFunctor accumulate;
713 my_transform(7, data, result, accumulate);
714
715 std::cout << "Result is [ ";
716 for (size_t i = 0; i < 7; i++)
717 std::cout << result[i] << ' ';
718 std::cout << "]\n";
719 return 0;
720}
721```
722
723C++11 adds anonymous ("lambda") functions, which can be stored in variables and passed to functions. They can optionally serve as closures, meaning they can reference state from parent scopes. This feature greatly simplifies ` my_transform `:
724
ratchetfreak24688932016-10-27 18:02:14 +0200725```C++
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100726// C++11
727#include <iostream>
728#include <cstddef>
729#include <functional>
730
731void my_transform (size_t n_elts, int* in, int* out, std::function<int(int)> op)
732{
733 size_t i;
734
735 for (i = 0; i < n_elts; i++)
736 out[i] = op(in[i]);
737}
738
739int main (void)
740{
741 int data[7] = {8, 6, 7, 5, 3, 0, 9};
742 int result[7];
743 int total = 0;
744 my_transform(7, data, result, [&total] (int v) {
745 total += v;
746 return total;
747 });
748
749 std::cout << "Result is [ ";
750 for (size_t i = 0; i < 7; i++)
751 std::cout << result[i] << ' ';
752 std::cout << "]\n";
753 return 0;
754}
755```
756
757A typical Go version of ` my_transform ` looks a lot like the C++11 version:
758
ratchetfreak24688932016-10-27 18:02:14 +0200759```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100760package main
761
762import "fmt"
763
764func my_transform(in []int, xform func(int) int) (out []int) {
765 out = make([]int, len(in))
766 for idx, val := range in {
767 out[idx] = xform(val)
768 }
769 return
770}
771
772func main() {
773 data := []int{8, 6, 7, 5, 3, 0, 9}
774 total := 0
775 fmt.Printf("Result is %v\n", my_transform(data, func(v int) int {
776 total += v
777 return total
778 }))
779}
780```
781
782(Note that we chose to return ` out ` from ` my_transform ` rather than pass it an ` out ` to write to. This was an aesthetic decision; the code could have been written more like the C++ version in that regard.)
783
784In Go, functions are always full closures, the equivalent of ` [&] ` in C++11. An important difference is that it is invalid in C++11 for a closure to reference a variable whose scope has gone away (as may be caused by an <a href='http://en.wikipedia.org/wiki/Funarg_problem'>upward funarg</a>—a function that returns a lambda that references local variables). In Go, this is perfectly valid.
785
786
787<h2>Concurrency</h2>
788
789Like C++11's ` std::thread `, Go permits starting new threads of execution that run concurrently in a shared address space. These are called _goroutines_ and are spawned using the ` go ` statement. While typical ` std::thread ` implementations launch heavyweight, operating-system threads, goroutines are implemented as lightweight, user-level threads that are multiplexed among multiple operating-system threads. Consequently, goroutines are (intended to be) cheap and can be used liberally throughout a program.
790
ratchetfreak24688932016-10-27 18:02:14 +0200791```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100792func server(i int) {
793 for {
794 fmt.Print(i)
795 time.Sleep(10 * time.Second)
796 }
797}
798go server(1)
799go server(2)
800```
801
802(Note that the ` for ` statement in the ` server `
803function is equivalent to a C++ ` while (true) ` loop.)
804
805Function literals (which Go implements as closures)
806can be useful with the ` go ` statement.
807
ratchetfreak24688932016-10-27 18:02:14 +0200808```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100809var g int
810go func(i int) {
811 s := 0
Dave Day0d6986a2014-12-10 15:02:18 +1100812 for j := 0; j < i; j++ {
813 s += j
814 }
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100815 g = s
Dave Day0d6986a2014-12-10 15:02:18 +1100816}(1000) // Passes argument 1000 to the function literal.
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100817```
818
819Like C++11, but unlike prior versions of C++, Go defines a
820<a href='http://golang.org/ref/mem'>memory model</a> for unsynchronized accesses to memory. Although Go provides an analogue of ` std::mutex ` in its ` sync ` package, this is not the normal way to implement inter-thread communication and synchronization in Go programs. Instead, Go threads more typically communicate by message passing, which is a fundamentally different approach from locks and barriers. The Go mantra for this subject is,
821
822> Do not communicate by sharing memory; instead, share memory by communicating.
823
824That is, _channels_ are used to communicate among goroutines. Values of any type (including other channels!) can be
825sent over a channel. Channels can be unbuffered or buffered (using a buffer length specified at channel-construction time).
826
827Channels are first-class values; they can be stored in variables and passed to and from functions like any other value. (When supplied to
828functions, channels are passed by reference.) Channels are also typed: a ` chan int ` is different from a ` chan string `.
829
830Because they are so widely used in Go programs, channels are (intended to be) efficient and cheap. To send a value on a channel, use ` <- ` as a binary operator. To receive a value on a channel, use ` <- ` as a unary operator. Channels can be shared among multiple senders and multiple receivers and guarantee that each value sent is received by at most one receiver.
831
832Here is an example of using a manager function to control access to a
833single value.
834
ratchetfreak24688932016-10-27 18:02:14 +0200835```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100836type Cmd struct { Get bool; Val int }
837func Manager(ch chan Cmd) {
838 val := 0
839 for {
840 c := <-ch
841 if c.Get { c.Val = val; ch <- c }
842 else { val = c.Val }
843 }
844}
845```
846
847In that example the same channel is used for input and output.
848This is incorrect if there are multiple goroutines communicating
849with the manager at once: a goroutine waiting for a response
850from the manager might receive a request from another goroutine
851instead.
852A solution is to pass in a channel.
853
ratchetfreak24688932016-10-27 18:02:14 +0200854```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100855type Cmd2 struct { Get bool; Val int; Ch chan<- int }
856func Manager2(ch <-chan Cmd2) {
857 val := 0
858 for {
859 c := <-ch
860 if c.Get { c.Ch <- val }
861 else { val = c.Val }
862 }
863}
864```
865
866To use ` Manager2 `, given a channel to it:
867
ratchetfreak24688932016-10-27 18:02:14 +0200868```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100869func f4(ch chan<- Cmd2) int {
870 myCh := make(chan int)
Dave Day0d6986a2014-12-10 15:02:18 +1100871 c := Cmd2{true, 0, myCh} // Composite literal syntax.
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100872 ch <- c
873 return <-myCh
874}
875```