summaryrefslogtreecommitdiff
path: root/doc/go_for_cpp_programmers.html
diff options
context:
space:
mode:
Diffstat (limited to 'doc/go_for_cpp_programmers.html')
-rw-r--r--doc/go_for_cpp_programmers.html707
1 files changed, 707 insertions, 0 deletions
diff --git a/doc/go_for_cpp_programmers.html b/doc/go_for_cpp_programmers.html
new file mode 100644
index 000000000..7168f1d05
--- /dev/null
+++ b/doc/go_for_cpp_programmers.html
@@ -0,0 +1,707 @@
+<!-- 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&lt;string, int&gt;* 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 float64
+)
+</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 <code>for</code> 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>-&gt;</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 &lt; b { f() } // Valid
+if (a &lt; b) { f() } // Valid (condition is a parenthesized expression)
+if (a &lt; b) f() // INVALID
+for i = 0; i &lt; 10; i++ {} // Valid
+for (i = 0; i &lt; 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&mdash;or even integers;
+any type
+that supports the equality comparison operator, such as strings or
+pointers, can be used&mdash;and if the <code>switch</code>
+value is omitted it defaults to <code>true</code>.
+
+<pre>
+switch {
+case i &lt; 0:
+ f1()
+case i == 0:
+ f2()
+case i &gt; 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 &lt;&lt; 100
+f(huge &gt;&gt; 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 = &amp;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(&amp;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(&amp;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 run time, 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 run time, 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 &lt; 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>&lt;-</code> as a binary
+operator. To
+receive a value on a channel, use <code>&lt;-</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 := &lt;- ch
+ if c.get { c.val = val; ch &lt;- 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 &lt;- chan int }
+func manager2(ch chan cmd2) {
+ var val int = 0
+ for {
+ c := &lt;- ch
+ if c.get { c.ch &lt;- val }
+ else { val = c.val }
+ }
+}
+</pre>
+
+<p>
+To use <code>manager2</code>, given a channel to it:
+
+<pre>
+func f4(ch &lt;- chan cmd2) int {
+ myCh := make(chan int)
+ c := cmd2{ true, 0, myCh } // Composite literal syntax.
+ ch &lt;- c
+ return &lt;-myCh
+}
+</pre>