mirror of
				https://github.com/golang/go.git
				synced 2025-10-31 16:50:58 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			707 lines
		
	
	
	
		
			21 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			707 lines
		
	
	
	
		
			21 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <!-- Go For C++ Programmers -->
 | |
| 
 | |
| <p>
 | |
| Go is a systems programming language intended to be a general-purpose
 | |
| systems language, like C++.
 | |
| These are some notes on Go for experienced C++ programmers. This
 | |
| document discusses the differences between Go and C++, and says little
 | |
| to nothing about the similarities.
 | |
| 
 | |
| <p>
 | |
| For a more general introduction to Go, see the
 | |
| <a href="go_tutorial.html">Go tutorial</a> and
 | |
| <a href="effective_go.html">Effective Go</a>.
 | |
| 
 | |
| <p>
 | |
| For a detailed description of the Go language, see the
 | |
| <a href="go_spec.html">Go spec</a>.
 | |
| 
 | |
| <h2 id="Conceptual_Differences">Conceptual Differences</h2>
 | |
| 
 | |
| <ul>
 | |
| <li>Go does not have classes with constructors or destructors.
 | |
|     Instead of class methods, a class inheritance hierarchy,
 | |
|     and virtual functions, Go provides <em>interfaces</em>, which are
 | |
|     <a href="#Interfaces">discussed in more detail below</a>.
 | |
|     Interfaces are also used where C++ uses templates.
 | |
| 
 | |
| <li>Go uses garbage collection. It is not necessary (or possible)
 | |
|     to release memory explicitly. The garbage collection is (intended to be)
 | |
|     incremental and highly efficient on modern processors.
 | |
| 
 | |
| <li>Go has pointers but not pointer arithmetic. You cannot
 | |
|     use a pointer variable to walk through the bytes of a string.
 | |
| 
 | |
| <li>Arrays in Go are first class values. When an array is used as a
 | |
|     function parameter, the function receives a copy of the array, not
 | |
|     a pointer to it. However, in practice functions often use slices
 | |
|     for parameters; slices hold pointers to underlying arrays.  Slices
 | |
|     are <a href="#Slices">discussed further below</a>.
 | |
| 
 | |
| <li>Strings are provided by the language. They may not be changed once they
 | |
|     have been created.
 | |
| 
 | |
| <li>Hash tables are provided by the language. They are called maps.
 | |
| 
 | |
| <li>Separate threads of execution, and communication channels between
 | |
|     them, are provided by the language. This
 | |
|     is <a href="#Goroutines">discussed further below</a>.
 | |
| 
 | |
| <li>Certain types (maps and channels, described further below)
 | |
|     are passed by reference, not by value. That is, passing a map to a
 | |
|     function does not copy the map, and if the function changes the map
 | |
|     the change will be seen by the caller.  In C++ terms, one can
 | |
|     think of these as being reference types.
 | |
| 
 | |
| <li>Go does not use header files. Instead, each source file is part of a
 | |
|     defined <em>package</em>. When a package defines an object
 | |
|     (type, constant, variable, function) with a name starting with an
 | |
|     upper case letter, that object is visible to any other file which
 | |
|     imports that package.
 | |
| 
 | |
| <li>Go does not support implicit type conversion. Operations that mix
 | |
|     different types require casts (called conversions in Go).
 | |
| 
 | |
| <li>Go does not support function overloading and does not support user
 | |
|     defined operators.
 | |
| 
 | |
| <li>Go does not support <code>const</code> or <code>volatile</code> qualifiers.
 | |
| 
 | |
| <li>Go uses <code>nil</code> for invalid pointers, where C++ uses
 | |
|     <code>NULL</code> or simply <code>0</code>.
 | |
| </ul>
 | |
| 
 | |
| <h2 id="Syntax">Syntax</h2>
 | |
| 
 | |
| <p>
 | |
| The declaration syntax is reversed compared to C++. You write the name
 | |
| followed by the type. Unlike in C++, the syntax for a type does not match
 | |
| the way in which the variable is used. Type declarations may be read
 | |
| easily from left to right.
 | |
| 
 | |
| <pre>
 | |
| <b>Go                           C++</b>
 | |
| var v1 int                // int v1;
 | |
| var v2 string             // const std::string v2;  (approximately)
 | |
| var v3 [10]int            // int v3[10];
 | |
| var v4 []int              // int* v4;  (approximately)
 | |
| var v5 struct { f int }   // struct { int f; } v5;
 | |
| var v6 *int               // int* v6;  (but no pointer arithmetic)
 | |
| var v7 map[string]int     // unordered_map<string, int>* v7;  (approximately)
 | |
| var v8 func(a int) int    // int (*v8)(int a);
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| Declarations generally take the form of a keyword followed by the name
 | |
| of the object being declared.  The keyword is one of <code>var</code>,
 | |
| <code>func</code>,
 | |
| <code>const</code>, or <code>type</code>.  Method declarations are a minor
 | |
| exception in that
 | |
| the receiver appears before the name of the object being declared; see
 | |
| the <a href="#Interfaces">discussion of interfaces</a>.
 | |
| 
 | |
| <p>
 | |
| You can also use a keyword followed by a series of declarations in
 | |
| parentheses.
 | |
| 
 | |
| <pre>
 | |
| var (
 | |
|     i int
 | |
|     m float
 | |
| )
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| When declaring a function, you must either provide a name for each parameter
 | |
| or not provide a name for any parameter; you can't omit some names
 | |
| and provide others.  You may group several names with the same type:
 | |
| 
 | |
| <pre>
 | |
| func f(i, j, k int, s, t string)
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| A variable may be initialized when it is declared.  When this is done,
 | |
| specifying the type is permitted but not required.  When the type is
 | |
| not specified, the type of the variable is the type of the
 | |
| initialization expression.
 | |
| 
 | |
| <pre>
 | |
| var v = *p
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| See also the <a href="#Constants">discussion of constants, below</a>.
 | |
| If a variable is not initialized explicitly, the type must be specified.
 | |
| In that case it will be
 | |
| implicitly initialized to the type's zero value (0, nil, etc.).  There are no
 | |
| uninitialized variables in Go.
 | |
| 
 | |
| <p>
 | |
| Within a function, a short declaration syntax is available with
 | |
| <code>:=</code> .
 | |
| 
 | |
| <pre>
 | |
| v1 := v2
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| This is equivalent to
 | |
| 
 | |
| <pre>
 | |
| var v1 = v2
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| Go permits multiple assignments, which are done in parallel.
 | |
| 
 | |
| <pre>
 | |
| i, j = j, i    // Swap i and j.
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| Functions may have multiple return values, indicated by a list in
 | |
| parentheses.  The returned values can be stored by assignment
 | |
| to a list of variables.
 | |
| 
 | |
| <pre>
 | |
| func f() (i int, j int) { ... }
 | |
| v1, v2 = f()
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| Go code uses very few semicolons in practice.  Technically, all Go
 | |
| statements are terminated by a semicolon.  However, Go treats the end
 | |
| of a non-blank line as a semicolon unless the line is clearly
 | |
| incomplete (the exact rules are
 | |
| in <a href="go_spec.html#Semicolons">the language specification</a>).
 | |
| A consequence of this is that in some cases Go does not permit you to
 | |
| use a line break.  For example, you may not write
 | |
| <pre>
 | |
| func g()
 | |
| {                  // INVALID
 | |
| }
 | |
| </pre>
 | |
| A semicolon will be inserted after <code>g()</code>, causing it to be
 | |
| a function declaration rather than a function definition.  Similarly,
 | |
| you may not write
 | |
| <pre>
 | |
| if x {
 | |
| }
 | |
| else {             // INVALID
 | |
| }
 | |
| </pre>
 | |
| A semicolon will be inserted after the <code>}</code> preceding
 | |
| the <code>else</code>, causing a syntax error.
 | |
| 
 | |
| <p>
 | |
| Since semicolons do end statements, you may continue using them as in
 | |
| C++.  However, that is not the recommended style.  Idiomatic Go code
 | |
| omits unnecessary semicolons, which in practice is all of them other
 | |
| than the initial <for> loop clause and cases where you want several
 | |
| short statements on a single line.
 | |
| 
 | |
| <p>
 | |
| While we're on the topic, we recommend that rather than worry about
 | |
| semicolons and brace placement, you format your code with
 | |
| the <code>gofmt</code> program.  That will produce a single standard
 | |
| Go style, and let you worry about your code rather than your
 | |
| formatting.  While the style may initially seem odd, it is as good as
 | |
| any other style, and familiarity will lead to comfort.
 | |
| 
 | |
| <p>
 | |
| When using a pointer to a struct, you use <code>.</code> instead
 | |
| of <code>-></code>.
 | |
| Thus syntactically speaking a structure and a pointer to a structure
 | |
| are used in the same way.
 | |
| 
 | |
| <pre>
 | |
| type myStruct struct { i int }
 | |
| var v9 myStruct              // v9 has structure type
 | |
| var p9 *myStruct             // p9 is a pointer to a structure
 | |
| f(v9.i, p9.i)
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| Go does not require parentheses around the condition of a <code>if</code>
 | |
| statement, or the expressions of a <code>for</code> statement, or the value of a
 | |
| <code>switch</code> statement.  On the other hand, it does require curly braces
 | |
| around the body of an <code>if</code> or <code>for</code> statement.
 | |
| 
 | |
| <pre>
 | |
| if a < b { f() }             // Valid
 | |
| if (a < b) { f() }           // Valid (condition is a parenthesized expression)
 | |
| if (a < b) f()               // INVALID
 | |
| for i = 0; i < 10; i++ {}    // Valid
 | |
| for (i = 0; i < 10; i++) {}  // INVALID
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| Go does not have a <code>while</code> statement nor does it have a
 | |
| <code>do/while</code>
 | |
| statement.  The <code>for</code> statement may be used with a single condition,
 | |
| which makes it equivalent to a <code>while</code> statement.  Omitting the
 | |
| condition entirely is an endless loop.
 | |
| 
 | |
| <p>
 | |
| Go permits <code>break</code> and <code>continue</code> to specify a label.
 | |
| The label must
 | |
| refer to a <code>for</code>, <code>switch</code>, or <code>select</code>
 | |
| statement.
 | |
| 
 | |
| <p>
 | |
| In a <code>switch</code> statement, <code>case</code> labels do not fall
 | |
| through.  You can
 | |
| make them fall through using the <code>fallthrough</code> keyword.  This applies
 | |
| even to adjacent cases.
 | |
| 
 | |
| <pre>
 | |
| switch i {
 | |
| case 0:  // empty case body
 | |
| case 1:
 | |
|     f()  // f is not called when i == 0!
 | |
| }
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| But a <code>case</code> can have multiple values.
 | |
| 
 | |
| <pre>
 | |
| switch i {
 | |
| case 0, 1:
 | |
|     f()  // f is called if i == 0 || i == 1.
 | |
| }
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| The values in a <code>case</code> need not be constants—or even integers;
 | |
| any type
 | |
| that supports the equality comparison operator, such as strings or
 | |
| pointers, can be used—and if the <code>switch</code>
 | |
| value is omitted it defaults to <code>true</code>.
 | |
| 
 | |
| <pre>
 | |
| switch {
 | |
| case i < 0:
 | |
|     f1()
 | |
| case i == 0:
 | |
|     f2()
 | |
| case i > 0:
 | |
|     f3()
 | |
| }
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| The <code>++</code> and <code>--</code> operators may only be used in
 | |
| statements, not in expressions.
 | |
| You cannot write <code>c = *p++</code>.  <code>*p++</code> is parsed as
 | |
| <code>(*p)++</code>.
 | |
| 
 | |
| <p>
 | |
| The <code>defer</code> statement may be used to call a function after
 | |
| the function containing the <code>defer</code> statement returns.
 | |
| 
 | |
| <pre>
 | |
| fd := open("filename")
 | |
| defer close(fd)         // fd will be closed when this function returns.
 | |
| </pre>
 | |
| 
 | |
| <h2 id="Constants">Constants </h2>
 | |
| 
 | |
| <p>
 | |
| In Go constants may be <i>untyped</i>. This applies even to constants
 | |
| named with a <code>const</code> declaration, if no
 | |
| type is given in the declaration and the initializer expression uses only
 | |
| untyped constants.
 | |
| A value derived from an untyped constant becomes typed when it
 | |
| is used within a context that
 | |
| requires a typed value. This permits constants to be used relatively
 | |
| freely without requiring general implicit type conversion.
 | |
| 
 | |
| <pre>
 | |
| var a uint
 | |
| f(a + 1)  // untyped numeric constant "1" becomes typed as uint
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| The language does not impose any limits on the size of an untyped
 | |
| numeric constant or constant expression. A limit is only applied when
 | |
| a constant is used where a type is required.
 | |
| 
 | |
| <pre>
 | |
| const huge = 1 << 100
 | |
| f(huge >> 98)
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| Go does not support enums.  Instead, you can use the special name
 | |
| <code>iota</code> in a single <code>const</code> declaration to get a
 | |
| series of increasing
 | |
| value.  When an initialization expression is omitted for a <code>const</code>,
 | |
| it reuses the preceding expression.
 | |
| 
 | |
| <pre>
 | |
| const (
 | |
|     red = iota   // red == 0
 | |
|     blue         // blue == 1
 | |
|     green        // green == 2
 | |
| )
 | |
| </pre>
 | |
| 
 | |
| <h2 id="Slices">Slices</h2>
 | |
| 
 | |
| <p>
 | |
| A slice is conceptually a struct with three fields: a
 | |
| pointer to an array, a length, and a capacity.
 | |
| Slices support
 | |
| the <code>[]</code> operator to access elements of the underlying array.
 | |
| The builtin
 | |
| <code>len</code> function returns the
 | |
| length of the slice.  The builtin <code>cap</code> function returns the
 | |
| capacity.
 | |
| 
 | |
| <p>
 | |
| Given an array, or another slice, a new slice is created via
 | |
| <code>a[I:J]</code>.  This
 | |
| creates a new slice which refers to <code>a</code>, starts at
 | |
| index <code>I</code>, and ends before index
 | |
| <code>J</code>.  It has length <code>J - I</code>.
 | |
| The new slice refers to the same array
 | |
| to which <code>a</code>
 | |
| refers.  That is, changes made using the new slice may be seen using
 | |
| <code>a</code>.  The
 | |
| capacity of the new slice is simply the capacity of <code>a</code> minus
 | |
| <code>I</code>.  The capacity
 | |
| of an array is the length of the array.  You may also assign an array pointer
 | |
| to a variable of slice type; given <code>var s []int; var a[10] int</code>,
 | |
| the assignment <code>s = &a</code> is equivalent to
 | |
| <code>s = a[0:len(a)]</code>.
 | |
| 
 | |
| <p>
 | |
| What this means is that Go uses slices for some cases where C++ uses pointers.
 | |
| If you create a value of type <code>[100]byte</code> (an array of 100 bytes,
 | |
| perhaps a
 | |
| buffer) and you want to pass it to a function without copying it, you should
 | |
| declare the function parameter to have type <code>[]byte</code>, and pass the
 | |
| address
 | |
| of the array.  Unlike in C++, it is not
 | |
| necessary to pass the length of the buffer; it is efficiently accessible via
 | |
| <code>len</code>.
 | |
| 
 | |
| <p>
 | |
| The slice syntax may also be used with a string.  It returns a new string,
 | |
| whose value is a substring of the original string.
 | |
| Because strings are immutable, string slices can be implemented
 | |
| without allocating new storage for the slices's contents.
 | |
| 
 | |
| <h2 id="Making_values">Making values</h2>
 | |
| 
 | |
| <p>
 | |
| Go has a builtin function <code>new</code> which takes a type and
 | |
| allocates space
 | |
| on the heap. The allocated space will be zero-initialized for the type.
 | |
| For example, <code>new(int)</code> allocates a new int on the heap,
 | |
| initializes it with the value <code>0</code>,
 | |
| and returns its address, which has type <code>*int</code>.
 | |
| Unlike in C++, <code>new</code> is a function, not an operator;
 | |
| <code>new int</code> is a syntax error.
 | |
| 
 | |
| <p>
 | |
| Map and channel values must be allocated using the builtin function
 | |
| <code>make</code>.
 | |
| A variable declared with map or channel type without an initializer will be
 | |
| automatically initialized to <code>nil</code>.
 | |
| Calling <code>make(map[int]int)</code> returns a newly allocated value of
 | |
| type <code>map[int]int</code>.
 | |
| Note that <code>make</code> returns a value, not a pointer.  This is
 | |
| consistent with
 | |
| the fact that map and channel values are passed by reference.  Calling
 | |
| <code>make</code> with
 | |
| a map type takes an optional argument which is the expected capacity of the
 | |
| map.  Calling <code>make</code> with a channel type takes an optional
 | |
| argument which sets the
 | |
| buffering capacity of the channel; the default is 0 (unbuffered).
 | |
| 
 | |
| <p>
 | |
| The <code>make</code> function may also be used to allocate a slice.
 | |
| In this case it
 | |
| allocates memory for the underlying array and returns a slice referring to it.
 | |
| There is one required argument, which is the number of elements in the slice.
 | |
| A second, optional, argument is the capacity of the slice.  For example,
 | |
| <code>make([]int, 10, 20)</code>.  This is identical to
 | |
| <code>new([20]int)[0:10]</code>.  Since
 | |
| Go uses garbage collection, the newly allocated array will be discarded
 | |
| sometime after there are no references to the returned slice.
 | |
| 
 | |
| <h2 id="Interfaces">Interfaces</h2>
 | |
| 
 | |
| <p>
 | |
| Where C++ provides classes, subclasses and templates,
 | |
| Go provides interfaces.  A
 | |
| Go interface is similar to a C++ pure abstract class: a class with no
 | |
| data members, with methods which are all pure virtual.  However, in
 | |
| Go, any type which provides the methods named in the interface may be
 | |
| treated as an implementation of the interface.  No explicitly declared
 | |
| inheritance is required.  The implementation of the interface is
 | |
| entirely separate from the interface itself.
 | |
| 
 | |
| <p>
 | |
| A method looks like an ordinary function definition, except that it
 | |
| has a <em>receiver</em>.  The receiver is similar to
 | |
| the <code>this</code> pointer in a C++ class method.
 | |
| 
 | |
| <pre>
 | |
| type myType struct { i int }
 | |
| func (p *myType) get() int { return p.i }
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| This declares a method <code>get</code> associated with <code>myType</code>.
 | |
| The receiver is named <code>p</code> in the body of the function.
 | |
| 
 | |
| <p>
 | |
| Methods are defined on named types.  If you convert the value
 | |
| to a different type, the new value will have the methods of the new type,
 | |
| not the old type.
 | |
| 
 | |
| <p>
 | |
| You may define methods on a builtin type by declaring a new named type
 | |
| derived from it.  The new type is distinct from the builtin type.
 | |
| 
 | |
| <pre>
 | |
| type myInteger int
 | |
| func (p myInteger) get() int { return int(p) } // Conversion required.
 | |
| func f(i int) { }
 | |
| var v myInteger
 | |
| // f(v) is invalid.
 | |
| // f(int(v)) is valid; int(v) has no defined methods.
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| Given this interface:
 | |
| 
 | |
| <pre>
 | |
| type myInterface interface {
 | |
| 	get() int
 | |
| 	set(i int)
 | |
| }
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| we can make <code>myType</code> satisfy the interface by adding
 | |
| 
 | |
| <pre>
 | |
| func (p *myType) set(i int) { p.i = i }
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| Now any function which takes <code>myInterface</code> as a parameter
 | |
| will accept a
 | |
| variable of type <code>*myType</code>.
 | |
| 
 | |
| <pre>
 | |
| func getAndSet(x myInterface) {}
 | |
| func f1() {
 | |
| 	var p myType
 | |
| 	getAndSet(&p)
 | |
| }
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| In other words, if we view <code>myInterface</code> as a C++ pure abstract
 | |
| base
 | |
| class, defining <code>set</code> and <code>get</code> for
 | |
| <code>*myType</code> made <code>*myType</code> automatically
 | |
| inherit from <code>myInterface</code>.  A type may satisfy multiple interfaces.
 | |
| 
 | |
| <p>
 | |
| An anonymous field may be used to implement something much like a C++ child
 | |
| class.
 | |
| 
 | |
| <pre>
 | |
| type myChildType struct { myType; j int }
 | |
| func (p *myChildType) get() int { p.j++; return p.myType.get() }
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| This effectively implements <code>myChildType</code> as a child of
 | |
| <code>myType</code>.
 | |
| 
 | |
| <pre>
 | |
| func f2() {
 | |
| 	var p myChildType
 | |
| 	getAndSet(&p)
 | |
| }
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| The <code>set</code> method is effectively inherited from
 | |
| <code>myChildType</code>, because
 | |
| methods associated with the anonymous field are promoted to become methods
 | |
| of the enclosing type.  In this case, because <code>myChildType</code> has an
 | |
| anonymous field of type <code>myType</code>, the methods of
 | |
| <code>myType</code> also become methods of <code>myChildType</code>.
 | |
| In this example, the <code>get</code> method was
 | |
| overridden, and the <code>set</code> method was inherited.
 | |
| 
 | |
| <p>
 | |
| This is not precisely the same as a child class in C++.
 | |
| When a method of an anonymous field is called,
 | |
| its receiver is the field, not the surrounding struct.
 | |
| In other words, methods on anonymous fields are not virtual functions.
 | |
| When you want the equivalent of a virtual function, use an interface.
 | |
| 
 | |
| <p>
 | |
| A variable which has an interface type may be converted to have a
 | |
| different interface type using a special construct called a type assertion.
 | |
| This is implemented dynamically
 | |
| at runtime, like C++ <code>dynamic_cast</code>.  Unlike
 | |
| <code>dynamic_cast</code>, there does
 | |
| not need to be any declared relationship between the two interfaces.
 | |
| 
 | |
| <pre>
 | |
| type myPrintInterface interface {
 | |
|   print()
 | |
| }
 | |
| func f3(x myInterface) {
 | |
| 	x.(myPrintInterface).print()  // type assertion to myPrintInterface
 | |
| }
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| The conversion to <code>myPrintInterface</code> is entirely dynamic.
 | |
| It will
 | |
| work as long as the underlying type of x (the <em>dynamic type</em>) defines
 | |
| a <code>print</code> method.
 | |
| 
 | |
| <p>
 | |
| Because the conversion is dynamic, it may be used to implement generic
 | |
| programming similar to templates in C++.  This is done by
 | |
| manipulating values of the minimal interface.
 | |
| 
 | |
| <pre>
 | |
| type Any interface { }
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| Containers may be written in terms of <code>Any</code>, but the caller
 | |
| must unbox using a type assertion to recover
 | |
| values of the contained type.  As the typing is dynamic rather
 | |
| than static, there is no equivalent of the way that a C++ template may
 | |
| inline the relevant operations.  The operations are fully type-checked
 | |
| at runtime, but all operations will involve a function call.
 | |
| 
 | |
| <pre>
 | |
| type iterator interface {
 | |
| 	get() Any
 | |
| 	set(v Any)
 | |
| 	increment()
 | |
| 	equal(arg *iterator) bool
 | |
| }
 | |
| </pre>
 | |
| 
 | |
| <h2 id="Goroutines">Goroutines</h2>
 | |
| 
 | |
| <p>
 | |
| Go permits starting a new thread of execution (a <em>goroutine</em>)
 | |
| using the <code>go</code>
 | |
| statement.  The <code>go</code> statement runs a function in a
 | |
| different, newly created, goroutine.
 | |
| All goroutines in a single program share the same address space.
 | |
| 
 | |
| <p>
 | |
| Internally, goroutines act like coroutines that are multiplexed among
 | |
| multiple operating system threads.  You do not have to worry
 | |
| about these details.
 | |
| 
 | |
| <pre>
 | |
| func server(i int) {
 | |
|     for {
 | |
|         print(i)
 | |
|         sys.sleep(10)
 | |
|     }
 | |
| }
 | |
| go server(1)
 | |
| go server(2)
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| (Note that the <code>for</code> statement in the <code>server</code>
 | |
| function is equivalent to a C++ <code>while (true)</code> loop.)
 | |
| 
 | |
| <p>
 | |
| Goroutines are (intended to be) cheap.
 | |
| 
 | |
| <p>
 | |
| Function literals (which Go implements as closures)
 | |
| can be useful with the <code>go</code> statement.
 | |
| 
 | |
| <pre>
 | |
| var g int
 | |
| go func(i int) {
 | |
| 	s := 0
 | |
| 	for j := 0; j < i; j++ { s += j }
 | |
| 	g = s
 | |
| }(1000)  // Passes argument 1000 to the function literal.
 | |
| </pre>
 | |
| 
 | |
| <h2 id="Channels">Channels</h2>
 | |
| 
 | |
| <p>
 | |
| Channels are used to communicate between goroutines.  Any value may be
 | |
| sent over a channel.  Channels are (intended to be) efficient and
 | |
| cheap.  To send a value on a channel, use <code><-</code> as a binary
 | |
| operator.  To
 | |
| receive a value on a channel, use <code><-</code> as a unary operator.
 | |
| When calling
 | |
| functions, channels are passed by reference.
 | |
| 
 | |
| <p>
 | |
| The Go library provides mutexes, but you can also use
 | |
| a single goroutine with a shared channel.
 | |
| Here is an example of using a manager function to control access to a
 | |
| single value.
 | |
| 
 | |
| <pre>
 | |
| type cmd struct { get bool; val int }
 | |
| func manager(ch chan cmd) {
 | |
| 	var val int = 0
 | |
| 	for {
 | |
| 		c := <- ch
 | |
| 		if c.get { c.val = val ch <- c }
 | |
| 		else { val = c.val }
 | |
| 	}
 | |
| }
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| In that example the same channel is used for input and output.
 | |
| This is incorrect if there are multiple goroutines communicating
 | |
| with the manager at once: a goroutine waiting for a response
 | |
| from the manager might receive a request from another goroutine
 | |
| instead.
 | |
| A solution is to pass in a channel.
 | |
| 
 | |
| <pre>
 | |
| type cmd2 struct { get bool; val int; ch <- chan int }
 | |
| func manager2(ch chan cmd2) {
 | |
| 	var val int = 0
 | |
| 	for {
 | |
| 		c := <- ch
 | |
| 		if c.get { c.ch <- val }
 | |
| 		else { val = c.val }
 | |
| 	}
 | |
| }
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| To use <code>manager2</code>, given a channel to it:
 | |
| 
 | |
| <pre>
 | |
| func f4(ch <- chan cmd2) int {
 | |
| 	myCh := make(chan int)
 | |
| 	c := cmd2{ true, 0, myCh }   // Composite literal syntax.
 | |
| 	ch <- c
 | |
| 	return <-myCh
 | |
| }
 | |
| </pre>
 | 
