1
0
mirror of https://github.com/golang/go synced 2024-11-14 07:00:21 -07:00

doc: update Go For C++ Programmers

Minor cleanups to look more like current Go.

R=golang-dev, r
CC=golang-dev
https://golang.org/cl/5707053
This commit is contained in:
Ian Lance Taylor 2012-02-28 16:49:57 -08:00
parent 9e7e6d9ea4
commit b69fa69a8b

View File

@ -8,16 +8,19 @@ systems language, like C++.
These are some notes on Go for experienced C++ programmers. This These are some notes on Go for experienced C++ programmers. This
document discusses the differences between Go and C++, and says little document discusses the differences between Go and C++, and says little
to nothing about the similarities. to nothing about the similarities.
</p>
<p> <p>
For a more general introduction to Go, see the For a more general introduction to Go, see the
<a href="http://tour.golang.org/">Go Tour</a>, <a href="http://tour.golang.org/">Go Tour</a>,
<a href="/doc/code.html">How to Write Go Code</a> <a href="/doc/code.html">How to Write Go Code</a>
and <a href="effective_go.html">Effective Go</a>. and <a href="effective_go.html">Effective Go</a>.
</p>
<p> <p>
For a detailed description of the Go language, see the For a detailed description of the Go language, see the
<a href="go_spec.html">Go spec</a>. <a href="go_spec.html">Go spec</a>.
</p>
<h2 id="Conceptual_Differences">Conceptual Differences</h2> <h2 id="Conceptual_Differences">Conceptual Differences</h2>
@ -29,8 +32,7 @@ For a detailed description of the Go language, see the
Interfaces are also used where C++ uses templates. Interfaces are also used where C++ uses templates.
<li>Go uses garbage collection. It is not necessary (or possible) <li>Go uses garbage collection. It is not necessary (or possible)
to release memory explicitly. The garbage collection is (intended to be) to release memory explicitly.
incremental and highly efficient on modern processors.
<li>Go has pointers but not pointer arithmetic. You cannot <li>Go has pointers but not pointer arithmetic. You cannot
use a pointer variable to walk through the bytes of a string. use a pointer variable to walk through the bytes of a string.
@ -81,6 +83,7 @@ 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 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 the way in which the variable is used. Type declarations may be read
easily from left to right. easily from left to right.
</p>
<pre> <pre>
<b>Go C++</b> <b>Go C++</b>
@ -102,10 +105,12 @@ of the object being declared. The keyword is one of <code>var</code>,
exception in that exception in that
the receiver appears before the name of the object being declared; see the receiver appears before the name of the object being declared; see
the <a href="#Interfaces">discussion of interfaces</a>. the <a href="#Interfaces">discussion of interfaces</a>.
</p>
<p> <p>
You can also use a keyword followed by a series of declarations in You can also use a keyword followed by a series of declarations in
parentheses. parentheses.
</p>
<pre> <pre>
var ( var (
@ -118,6 +123,7 @@ var (
When declaring a function, you must either provide a name for each parameter 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 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: and provide others. You may group several names with the same type:
</p>
<pre> <pre>
func f(i, j, k int, s, t string) func f(i, j, k int, s, t string)
@ -128,6 +134,7 @@ 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 specifying the type is permitted but not required. When the type is
not specified, the type of the variable is the type of the not specified, the type of the variable is the type of the
initialization expression. initialization expression.
</p>
<pre> <pre>
var v = *p var v = *p
@ -137,12 +144,15 @@ var v = *p
See also the <a href="#Constants">discussion of constants, below</a>. See also the <a href="#Constants">discussion of constants, below</a>.
If a variable is not initialized explicitly, the type must be specified. If a variable is not initialized explicitly, the type must be specified.
In that case it will be In that case it will be
implicitly initialized to the type's zero value (0, nil, etc.). There are no implicitly initialized to the type's zero value
(<code>0</code>, <code>nil</code>, etc.). There are no
uninitialized variables in Go. uninitialized variables in Go.
</p>
<p> <p>
Within a function, a short declaration syntax is available with Within a function, a short declaration syntax is available with
<code>:=</code> . <code>:=</code> .
</p>
<pre> <pre>
v1 := v2 v1 := v2
@ -150,6 +160,7 @@ v1 := v2
<p> <p>
This is equivalent to This is equivalent to
</p>
<pre> <pre>
var v1 = v2 var v1 = v2
@ -157,6 +168,7 @@ var v1 = v2
<p> <p>
Go permits multiple assignments, which are done in parallel. Go permits multiple assignments, which are done in parallel.
</p>
<pre> <pre>
i, j = j, i // Swap i and j. i, j = j, i // Swap i and j.
@ -166,6 +178,7 @@ i, j = j, i // Swap i and j.
Functions may have multiple return values, indicated by a list in Functions may have multiple return values, indicated by a list in
parentheses. The returned values can be stored by assignment parentheses. The returned values can be stored by assignment
to a list of variables. to a list of variables.
</p>
<pre> <pre>
func f() (i int, j int) { ... } func f() (i int, j int) { ... }
@ -180,22 +193,27 @@ incomplete (the exact rules are
in <a href="go_spec.html#Semicolons">the language specification</a>). 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 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 use a line break. For example, you may not write
</p>
<pre> <pre>
func g() func g()
{ // INVALID { // INVALID
} }
</pre> </pre>
<p>
A semicolon will be inserted after <code>g()</code>, causing it to be A semicolon will be inserted after <code>g()</code>, causing it to be
a function declaration rather than a function definition. Similarly, a function declaration rather than a function definition. Similarly,
you may not write you may not write
</p>
<pre> <pre>
if x { if x {
} }
else { // INVALID else { // INVALID
} }
</pre> </pre>
<p>
A semicolon will be inserted after the <code>}</code> preceding A semicolon will be inserted after the <code>}</code> preceding
the <code>else</code>, causing a syntax error. the <code>else</code>, causing a syntax error.
</p>
<p> <p>
Since semicolons do end statements, you may continue using them as in Since semicolons do end statements, you may continue using them as in
@ -203,6 +221,7 @@ C++. However, that is not the recommended style. Idiomatic Go code
omits unnecessary semicolons, which in practice is all of them other omits unnecessary semicolons, which in practice is all of them other
than the initial <code>for</code> loop clause and cases where you want several than the initial <code>for</code> loop clause and cases where you want several
short statements on a single line. short statements on a single line.
</p>
<p> <p>
While we're on the topic, we recommend that rather than worry about While we're on the topic, we recommend that rather than worry about
@ -211,12 +230,14 @@ the <code>gofmt</code> program. That will produce a single standard
Go style, and let you worry about your code rather than your 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 formatting. While the style may initially seem odd, it is as good as
any other style, and familiarity will lead to comfort. any other style, and familiarity will lead to comfort.
</p>
<p> <p>
When using a pointer to a struct, you use <code>.</code> instead When using a pointer to a struct, you use <code>.</code> instead
of <code>-&gt;</code>. of <code>-&gt;</code>.
Thus syntactically speaking a structure and a pointer to a structure Thus syntactically speaking a structure and a pointer to a structure
are used in the same way. are used in the same way.
</p>
<pre> <pre>
type myStruct struct { i int } type myStruct struct { i int }
@ -230,6 +251,7 @@ Go does not require parentheses around the condition of an <code>if</code>
statement, or the expressions of a <code>for</code> statement, or the value of a 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 <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. around the body of an <code>if</code> or <code>for</code> statement.
</p>
<pre> <pre>
if a &lt; b { f() } // Valid if a &lt; b { f() } // Valid
@ -245,18 +267,21 @@ Go does not have a <code>while</code> statement nor does it have a
statement. The <code>for</code> statement may be used with a single condition, 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 which makes it equivalent to a <code>while</code> statement. Omitting the
condition entirely is an endless loop. condition entirely is an endless loop.
</p>
<p> <p>
Go permits <code>break</code> and <code>continue</code> to specify a label. Go permits <code>break</code> and <code>continue</code> to specify a label.
The label must The label must
refer to a <code>for</code>, <code>switch</code>, or <code>select</code> refer to a <code>for</code>, <code>switch</code>, or <code>select</code>
statement. statement.
</p>
<p> <p>
In a <code>switch</code> statement, <code>case</code> labels do not fall In a <code>switch</code> statement, <code>case</code> labels do not fall
through. You can through. You can
make them fall through using the <code>fallthrough</code> keyword. This applies make them fall through using the <code>fallthrough</code> keyword. This applies
even to adjacent cases. even to adjacent cases.
</p>
<pre> <pre>
switch i { switch i {
@ -268,6 +293,7 @@ case 1:
<p> <p>
But a <code>case</code> can have multiple values. But a <code>case</code> can have multiple values.
</p>
<pre> <pre>
switch i { switch i {
@ -282,6 +308,7 @@ any type
that supports the equality comparison operator, such as strings or that supports the equality comparison operator, such as strings or
pointers, can be used&mdash;and if the <code>switch</code> pointers, can be used&mdash;and if the <code>switch</code>
value is omitted it defaults to <code>true</code>. value is omitted it defaults to <code>true</code>.
</p>
<pre> <pre>
switch { switch {
@ -299,10 +326,12 @@ The <code>++</code> and <code>--</code> operators may only be used in
statements, not in expressions. statements, not in expressions.
You cannot write <code>c = *p++</code>. <code>*p++</code> is parsed as You cannot write <code>c = *p++</code>. <code>*p++</code> is parsed as
<code>(*p)++</code>. <code>(*p)++</code>.
</p>
<p> <p>
The <code>defer</code> statement may be used to call a function after The <code>defer</code> statement may be used to call a function after
the function containing the <code>defer</code> statement returns. the function containing the <code>defer</code> statement returns.
</p>
<pre> <pre>
fd := open("filename") fd := open("filename")
@ -320,6 +349,7 @@ A value derived from an untyped constant becomes typed when it
is used within a context that is used within a context that
requires a typed value. This permits constants to be used relatively requires a typed value. This permits constants to be used relatively
freely without requiring general implicit type conversion. freely without requiring general implicit type conversion.
</p>
<pre> <pre>
var a uint var a uint
@ -330,6 +360,7 @@ f(a + 1) // untyped numeric constant "1" becomes typed as uint
The language does not impose any limits on the size of an untyped The language does not impose any limits on the size of an untyped
numeric constant or constant expression. A limit is only applied when numeric constant or constant expression. A limit is only applied when
a constant is used where a type is required. a constant is used where a type is required.
</p>
<pre> <pre>
const huge = 1 &lt;&lt; 100 const huge = 1 &lt;&lt; 100
@ -342,6 +373,7 @@ Go does not support enums. Instead, you can use the special name
series of increasing series of increasing
value. When an initialization expression is omitted for a <code>const</code>, value. When an initialization expression is omitted for a <code>const</code>,
it reuses the preceding expression. it reuses the preceding expression.
</p>
<pre> <pre>
const ( const (
@ -362,40 +394,43 @@ The builtin
<code>len</code> function returns the <code>len</code> function returns the
length of the slice. The builtin <code>cap</code> function returns the length of the slice. The builtin <code>cap</code> function returns the
capacity. capacity.
</p>
<p> <p>
Given an array, or another slice, a new slice is created via Given an array, or another slice, a new slice is created via
<code>a[I:J]</code>. This <code>a[i:j]</code>. This
creates a new slice which refers to <code>a</code>, starts at creates a new slice which refers to <code>a</code>, starts at
index <code>I</code>, and ends before index index <code>i</code>, and ends before index
<code>J</code>. It has length <code>J - I</code>. <code>j</code>. It has length <code>j-i</code>.
If <code>i</code> is omitted, the slice starts at <code>0</code>.
If <code>j</code> is omitted, the slice ends at <code>len(a)</code>.
The new slice refers to the same array The new slice refers to the same array
to which <code>a</code> to which <code>a</code>
refers. That is, changes made using the new slice may be seen using refers. That is, changes made using the new slice may be seen using
<code>a</code>. The <code>a</code>. The
capacity of the new slice is simply the capacity of <code>a</code> minus capacity of the new slice is simply the capacity of <code>a</code> minus
<code>I</code>. The capacity <code>i</code>. The capacity
of an array is the length of the array. You may also assign an array pointer of an array is the length of the array.
to a variable of slice type; given <code>var s []int; var a[10] int</code>, </p>
the assignment <code>s = &amp;a</code> is equivalent to
<code>s = a[0:len(a)]</code>.
<p> <p>
What this means is that Go uses slices for some cases where C++ uses pointers. 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, If you create a value of type <code>[100]byte</code> (an array of 100 bytes,
perhaps a perhaps a
buffer) and you want to pass it to a function without copying it, you should 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 declare the function parameter to have type <code>[]byte</code>, and
address pass a slice of the array (<code>a[:]</code> will pass the entire array).
of the array. Unlike in C++, it is not Unlike in C++, it is not
necessary to pass the length of the buffer; it is efficiently accessible via necessary to pass the length of the buffer; it is efficiently accessible via
<code>len</code>. <code>len</code>.
</p>
<p> <p>
The slice syntax may also be used with a string. It returns a new string, The slice syntax may also be used with a string. It returns a new string,
whose value is a substring of the original string. whose value is a substring of the original string.
Because strings are immutable, string slices can be implemented Because strings are immutable, string slices can be implemented
without allocating new storage for the slices's contents. without allocating new storage for the slices's contents.
</p>
<h2 id="Making_values">Making values</h2> <h2 id="Making_values">Making values</h2>
@ -408,6 +443,33 @@ initializes it with the value <code>0</code>,
and returns its address, which has type <code>*int</code>. and returns its address, which has type <code>*int</code>.
Unlike in C++, <code>new</code> is a function, not an operator; Unlike in C++, <code>new</code> is a function, not an operator;
<code>new int</code> is a syntax error. <code>new int</code> is a syntax error.
</p>
<p>
Perhaps surprisingly, <code>new</code> is not commonly used in Go
programs. In Go taking the address of a variable is always safe and
never yields a dangling pointer. If the program takes the address of
a variable, it will be allocated on the heap if necessary. So these
functions are equivalent:
</p>
<pre>
type S { I int }
func f1() *S {
return new(S)
}
func f2() *S {
var s S
return &amp;s
}
func f3() *S {
// More idiomatic: use composite literal syntax.
return &amp;S{0}
}
</pre>
<p> <p>
Map and channel values must be allocated using the builtin function Map and channel values must be allocated using the builtin function
@ -424,6 +486,7 @@ 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 map. Calling <code>make</code> with a channel type takes an optional
argument which sets the argument which sets the
buffering capacity of the channel; the default is 0 (unbuffered). buffering capacity of the channel; the default is 0 (unbuffered).
</p>
<p> <p>
The <code>make</code> function may also be used to allocate a slice. The <code>make</code> function may also be used to allocate a slice.
@ -435,6 +498,7 @@ A second, optional, argument is the capacity of the slice. For example,
<code>new([20]int)[0:10]</code>. Since <code>new([20]int)[0:10]</code>. Since
Go uses garbage collection, the newly allocated array will be discarded Go uses garbage collection, the newly allocated array will be discarded
sometime after there are no references to the returned slice. sometime after there are no references to the returned slice.
</p>
<h2 id="Interfaces">Interfaces</h2> <h2 id="Interfaces">Interfaces</h2>
@ -447,33 +511,38 @@ Go, any type which provides the methods named in the interface may be
treated as an implementation of the interface. No explicitly declared treated as an implementation of the interface. No explicitly declared
inheritance is required. The implementation of the interface is inheritance is required. The implementation of the interface is
entirely separate from the interface itself. entirely separate from the interface itself.
</p>
<p> <p>
A method looks like an ordinary function definition, except that it A method looks like an ordinary function definition, except that it
has a <em>receiver</em>. The receiver is similar to has a <em>receiver</em>. The receiver is similar to
the <code>this</code> pointer in a C++ class method. the <code>this</code> pointer in a C++ class method.
</p>
<pre> <pre>
type myType struct { i int } type myType struct { i int }
func (p *myType) get() int { return p.i } func (p *myType) Get() int { return p.i }
</pre> </pre>
<p> <p>
This declares a method <code>get</code> associated with <code>myType</code>. 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. The receiver is named <code>p</code> in the body of the function.
</p>
<p> <p>
Methods are defined on named types. If you convert the value 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, to a different type, the new value will have the methods of the new type,
not the old type. not the old type.
</p>
<p> <p>
You may define methods on a builtin type by declaring a new named type 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. derived from it. The new type is distinct from the builtin type.
</p>
<pre> <pre>
type myInteger int type myInteger int
func (p myInteger) get() int { return int(p) } // Conversion required. func (p myInteger) Get() int { return int(p) } // Conversion required.
func f(i int) { } func f(i int) { }
var v myInteger var v myInteger
// f(v) is invalid. // f(v) is invalid.
@ -482,58 +551,64 @@ var v myInteger
<p> <p>
Given this interface: Given this interface:
</p>
<pre> <pre>
type myInterface interface { type myInterface interface {
get() int Get() int
set(i int) Set(i int)
} }
</pre> </pre>
<p> <p>
we can make <code>myType</code> satisfy the interface by adding we can make <code>myType</code> satisfy the interface by adding
</p>
<pre> <pre>
func (p *myType) set(i int) { p.i = i } func (p *myType) Set(i int) { p.i = i }
</pre> </pre>
<p> <p>
Now any function which takes <code>myInterface</code> as a parameter Now any function which takes <code>myInterface</code> as a parameter
will accept a will accept a
variable of type <code>*myType</code>. variable of type <code>*myType</code>.
</p>
<pre> <pre>
func getAndSet(x myInterface) {} func GetAndSet(x myInterface) {}
func f1() { func f1() {
var p myType var p myType
getAndSet(&amp;p) GetAndSet(&amp;p)
} }
</pre> </pre>
<p> <p>
In other words, if we view <code>myInterface</code> as a C++ pure abstract In other words, if we view <code>myInterface</code> as a C++ pure abstract
base base
class, defining <code>set</code> and <code>get</code> for class, defining <code>Set</code> and <code>Get</code> for
<code>*myType</code> made <code>*myType</code> automatically <code>*myType</code> made <code>*myType</code> automatically
inherit from <code>myInterface</code>. A type may satisfy multiple interfaces. inherit from <code>myInterface</code>. A type may satisfy multiple interfaces.
</p>
<p> <p>
An anonymous field may be used to implement something much like a C++ child An anonymous field may be used to implement something much like a C++ child
class. class.
</p>
<pre> <pre>
type myChildType struct { myType; j int } type myChildType struct { myType; j int }
func (p *myChildType) get() int { p.j++; return p.myType.get() } func (p *myChildType) Get() int { p.j++; return p.myType.Get() }
</pre> </pre>
<p> <p>
This effectively implements <code>myChildType</code> as a child of This effectively implements <code>myChildType</code> as a child of
<code>myType</code>. <code>myType</code>.
</p>
<pre> <pre>
func f2() { func f2() {
var p myChildType var p myChildType
getAndSet(&amp;p) GetAndSet(&amp;p)
} }
</pre> </pre>
@ -544,8 +619,9 @@ methods associated with the anonymous field are promoted to become methods
of the enclosing type. In this case, because <code>myChildType</code> has an of the enclosing type. In this case, because <code>myChildType</code> has an
anonymous field of type <code>myType</code>, the methods of anonymous field of type <code>myType</code>, the methods of
<code>myType</code> also become methods of <code>myChildType</code>. <code>myType</code> also become methods of <code>myChildType</code>.
In this example, the <code>get</code> method was In this example, the <code>Get</code> method was
overridden, and the <code>set</code> method was inherited. overridden, and the <code>Set</code> method was inherited.
</p>
<p> <p>
This is not precisely the same as a child class in C++. This is not precisely the same as a child class in C++.
@ -553,21 +629,23 @@ When a method of an anonymous field is called,
its receiver is the field, not the surrounding struct. its receiver is the field, not the surrounding struct.
In other words, methods on anonymous fields are not virtual functions. In other words, methods on anonymous fields are not virtual functions.
When you want the equivalent of a virtual function, use an interface. When you want the equivalent of a virtual function, use an interface.
</p>
<p> <p>
A variable which has an interface type may be converted to have a A variable that has an interface type may be converted to have a
different interface type using a special construct called a type assertion. different interface type using a special construct called a type assertion.
This is implemented dynamically This is implemented dynamically
at run time, like C++ <code>dynamic_cast</code>. Unlike at run time, like C++ <code>dynamic_cast</code>. Unlike
<code>dynamic_cast</code>, there does <code>dynamic_cast</code>, there does
not need to be any declared relationship between the two interfaces. not need to be any declared relationship between the two interfaces.
</p>
<pre> <pre>
type myPrintInterface interface { type myPrintInterface interface {
print() Print()
} }
func f3(x myInterface) { func f3(x myInterface) {
x.(myPrintInterface).print() // type assertion to myPrintInterface x.(myPrintInterface).Print() // type assertion to myPrintInterface
} }
</pre> </pre>
@ -576,11 +654,13 @@ The conversion to <code>myPrintInterface</code> is entirely dynamic.
It will It will
work as long as the underlying type of x (the <em>dynamic type</em>) defines work as long as the underlying type of x (the <em>dynamic type</em>) defines
a <code>print</code> method. a <code>print</code> method.
</p>
<p> <p>
Because the conversion is dynamic, it may be used to implement generic Because the conversion is dynamic, it may be used to implement generic
programming similar to templates in C++. This is done by programming similar to templates in C++. This is done by
manipulating values of the minimal interface. manipulating values of the minimal interface.
</p>
<pre> <pre>
type Any interface { } type Any interface { }
@ -593,16 +673,24 @@ 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 than static, there is no equivalent of the way that a C++ template may
inline the relevant operations. The operations are fully type-checked inline the relevant operations. The operations are fully type-checked
at run time, but all operations will involve a function call. at run time, but all operations will involve a function call.
</p>
<pre> <pre>
type iterator interface { type Iterator interface {
get() Any Get() Any
set(v Any) Set(v Any)
increment() Increment()
equal(arg *iterator) bool Equal(arg Iterator) bool
} }
</pre> </pre>
<p>
Note that <code>Equal</code> has an argument of
type <code>Iterator</code>. This does not behave like a C++
template. See <a href="go_faq.html#t_and_equal_interface">the
FAQ</a>.
</p>
<h2 id="Goroutines">Goroutines</h2> <h2 id="Goroutines">Goroutines</h2>
<p> <p>
@ -611,17 +699,19 @@ using the <code>go</code>
statement. The <code>go</code> statement runs a function in a statement. The <code>go</code> statement runs a function in a
different, newly created, goroutine. different, newly created, goroutine.
All goroutines in a single program share the same address space. All goroutines in a single program share the same address space.
</p>
<p> <p>
Internally, goroutines act like coroutines that are multiplexed among Internally, goroutines act like coroutines that are multiplexed among
multiple operating system threads. You do not have to worry multiple operating system threads. You do not have to worry
about these details. about these details.
</p>
<pre> <pre>
func server(i int) { func server(i int) {
for { for {
print(i) fmt.Print(i)
sys.sleep(10) time.Sleep(10 * time.Second)
} }
} }
go server(1) go server(1)
@ -631,13 +721,16 @@ go server(2)
<p> <p>
(Note that the <code>for</code> statement in the <code>server</code> (Note that the <code>for</code> statement in the <code>server</code>
function is equivalent to a C++ <code>while (true)</code> loop.) function is equivalent to a C++ <code>while (true)</code> loop.)
</p>
<p> <p>
Goroutines are (intended to be) cheap. Goroutines are (intended to be) cheap.
</p>
<p> <p>
Function literals (which Go implements as closures) Function literals (which Go implements as closures)
can be useful with the <code>go</code> statement. can be useful with the <code>go</code> statement.
</p>
<pre> <pre>
var g int var g int
@ -658,21 +751,23 @@ operator. To
receive a value on a channel, use <code>&lt;-</code> as a unary operator. receive a value on a channel, use <code>&lt;-</code> as a unary operator.
When calling When calling
functions, channels are passed by reference. functions, channels are passed by reference.
</p>
<p> <p>
The Go library provides mutexes, but you can also use The Go library provides mutexes, but you can also use
a single goroutine with a shared channel. a single goroutine with a shared channel.
Here is an example of using a manager function to control access to a Here is an example of using a manager function to control access to a
single value. single value.
</p>
<pre> <pre>
type cmd struct { get bool; val int } type Cmd struct { Get bool; Val int }
func manager(ch chan cmd) { func Manager(ch chan Cmd) {
var val int = 0 val := 0
for { for {
c := &lt;-ch c := &lt;-ch
if c.get { c.val = val; ch &lt;- c } if c.Get { c.Val = val; ch &lt;- c }
else { val = c.val } else { val = c.Val }
} }
} }
</pre> </pre>
@ -684,26 +779,28 @@ with the manager at once: a goroutine waiting for a response
from the manager might receive a request from another goroutine from the manager might receive a request from another goroutine
instead. instead.
A solution is to pass in a channel. A solution is to pass in a channel.
</p>
<pre> <pre>
type cmd2 struct { get bool; val int; ch &lt;- chan int } type Cmd2 struct { Get bool; Val int; Ch &lt;- chan int }
func manager2(ch chan cmd2) { func Manager2(ch chan Cmd2) {
var val int = 0 val := 0
for { for {
c := &lt;-ch c := &lt;-ch
if c.get { c.ch &lt;- val } if c.Get { c.ch &lt;- val }
else { val = c.val } else { val = c.Val }
} }
} }
</pre> </pre>
<p> <p>
To use <code>manager2</code>, given a channel to it: To use <code>Manager2</code>, given a channel to it:
</p>
<pre> <pre>
func f4(ch &lt;- chan cmd2) int { func f4(ch &lt;- chan Cmd2) int {
myCh := make(chan int) myCh := make(chan int)
c := cmd2{ true, 0, myCh } // Composite literal syntax. c := Cmd2{ true, 0, myCh } // Composite literal syntax.
ch &lt;- c ch &lt;- c
return &lt;-myCh return &lt;-myCh
} }