mirror of
https://github.com/golang/go
synced 2024-11-22 00:44:39 -07:00
correct a few things in Go for C++ Programmers
R=iant, rsc CC=go-dev http://go/go-review/1016015
This commit is contained in:
parent
c2b6418c26
commit
6ac19ecefa
@ -8,14 +8,15 @@ to nothing about the similarities.
|
|||||||
|
|
||||||
<p>
|
<p>
|
||||||
For a more general introduction to Go, see the
|
For a more general introduction to Go, see the
|
||||||
<a href="go_tutorial.html">Go tutorial</a>.
|
<a href="go_tutorial.html">Go tutorial</a> and
|
||||||
|
<a href="effective_go.html">Effective Go</a>.
|
||||||
|
|
||||||
<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>
|
<p>
|
||||||
There is more <a href="./">documentation about go</a>.
|
There is more <a href="/">documentation about go</a>.
|
||||||
|
|
||||||
<h2 id="Conceptual_Differences">Conceptual Differences</h2>
|
<h2 id="Conceptual_Differences">Conceptual Differences</h2>
|
||||||
|
|
||||||
@ -56,8 +57,8 @@ There is more <a href="./">documentation about go</a>.
|
|||||||
|
|
||||||
<li>Go does not use header files. Instead, each source file is part of a
|
<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
|
defined <em>package</em>. When a package defines an object
|
||||||
(type, constant, variable, function) with a name which starts with an
|
(type, constant, variable, function) with a name starting with an
|
||||||
uppercase letter, than object is visible to any other file which
|
upper case letter, that object is visible to any other file which
|
||||||
imports that package.
|
imports that package.
|
||||||
|
|
||||||
<li>Go does not support implicit type conversion. Operations that mix
|
<li>Go does not support implicit type conversion. Operations that mix
|
||||||
@ -151,15 +152,16 @@ var v1 = v2;
|
|||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Go permits multiple assignments which are done in parallel.
|
Go permits multiple assignments, which are done in parallel.
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
i, j = j, i; // Swap i and j.
|
i, j = j, i; // Swap i and j.
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Functions may have multiple return values, indicating by a list in
|
Functions may have multiple return values, indicated by a list in
|
||||||
parentheses.
|
parentheses. The returned values can be stored by assignment
|
||||||
|
to a list of variables.
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
func f() (i int, j int);
|
func f() (i int, j int);
|
||||||
@ -195,9 +197,11 @@ statement, or the expressions of a <code>for</code> statement, or the value of a
|
|||||||
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.
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
if a < b { f() } // Valid
|
if a < b { f() } // Valid
|
||||||
if (a < b) { f() } // Valid
|
if (a < b) { f() } // Valid (condition is parenthesized expression)
|
||||||
if (a < b) f(); // INVALID
|
if (a < b) f(); // INVALID
|
||||||
|
for i = 0; i < 10; i++ {} // Valid
|
||||||
|
for (i = 0; i < 10; i++) {} // INVALID
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -263,7 +267,8 @@ In Go constants may be <i>untyped</i>. This applies even to constants
|
|||||||
named with a <code>const</code> declaration if no
|
named with a <code>const</code> declaration if no
|
||||||
type is given in the declaration and the initializer expression uses only
|
type is given in the declaration and the initializer expression uses only
|
||||||
untyped constants.
|
untyped constants.
|
||||||
An untyped constant becomes typed when it is used within a context that
|
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
|
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.
|
||||||
|
|
||||||
@ -309,7 +314,7 @@ Given an array, or another slice, a new slice is created via
|
|||||||
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 at index
|
index <code>I</code>, and ends at index
|
||||||
<code>J - 1</code>. It has length <code>J - I</code>.
|
<code>J - 1</code>. It has length <code>J - I</code>.
|
||||||
If <code>a</code> is itself a slice, 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
|
||||||
@ -335,6 +340,8 @@ necessary to pass the length of the buffer; it is efficiently accessible via
|
|||||||
<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
|
||||||
|
without allocating new storage for the slices's contents.
|
||||||
|
|
||||||
<h2 id="Making_values">Making values</h2>
|
<h2 id="Making_values">Making values</h2>
|
||||||
|
|
||||||
@ -342,10 +349,10 @@ whose value is a substring of the original string.
|
|||||||
Go has a builtin function <code>new</code> which takes a type and
|
Go has a builtin function <code>new</code> which takes a type and
|
||||||
allocates space
|
allocates space
|
||||||
on the heap. The allocated space will be zero-initialized for the type.
|
on the heap. The allocated space will be zero-initialized for the type.
|
||||||
For example, <code>new(int)</code> returns a new object of type
|
For example, <code>new(int)</code> allocates a new int on the heap,
|
||||||
<code>*int</code>,
|
initializes it with the value <code>0</code>,
|
||||||
allocated on the heap and initialized with the value <code>0</code>.
|
and returns its address, which has type <code>*int</code>.
|
||||||
Unlike 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>
|
||||||
@ -361,8 +368,8 @@ the fact that map and channel values are passed by reference. Calling
|
|||||||
<code>make</code> with
|
<code>make</code> with
|
||||||
a map type takes an optional argument which is the expected capacity of the
|
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 is the
|
argument which sets the
|
||||||
buffering capacity of the channel.
|
buffering capacity of the channel; the default is 0 (unbuffered).
|
||||||
|
|
||||||
<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.
|
||||||
@ -378,7 +385,8 @@ sometime after there are no references to the returned slice.
|
|||||||
<h2 id="Interfaces">Interfaces</h2>
|
<h2 id="Interfaces">Interfaces</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Where C++ provides classes and templates, Go provides interfaces. A
|
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
|
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
|
data members, with methods which are all pure virtual. However, in
|
||||||
Go, any type which provides the methods named in the interface may be
|
Go, any type which provides the methods named in the interface may be
|
||||||
@ -441,7 +449,7 @@ will accept a
|
|||||||
variable of type <code>*myType</code>.
|
variable of type <code>*myType</code>.
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
func getAndSet(x myInterface);
|
func getAndSet(x myInterface) {}
|
||||||
func f1() {
|
func f1() {
|
||||||
var p myType;
|
var p myType;
|
||||||
getAndSet(&p);
|
getAndSet(&p);
|
||||||
@ -495,22 +503,23 @@ you want the equivalent of a virtual function, use an interface.
|
|||||||
|
|
||||||
<p>
|
<p>
|
||||||
A variable which has an interface type may be converted to have a
|
A variable which has an interface type may be converted to have a
|
||||||
different interface type. This conversion is implemented dynamically
|
different interface type using a special construct called a type assertion.
|
||||||
|
This is implemented dynamically
|
||||||
at runtime, like C++ <code>dynamic_cast</code>. Unlike
|
at runtime, 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.
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
type myCompareInterface interface {
|
type myPrintInterface interface {
|
||||||
print();
|
print();
|
||||||
}
|
}
|
||||||
func f3(x myInterface) {
|
func f3(x myInterface) {
|
||||||
x.(myCompareInterface).print()
|
x.(myPrintInterface).print() // type assertion to myPrintInterface
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The conversion to <code>myCompareInterface</code> is entirely dynamic.
|
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.
|
||||||
@ -525,8 +534,9 @@ type Any interface { }
|
|||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Containers may be written in terms of <code>Any</code>, and the caller may cast
|
Containers may be written in terms of <code>Any</code>, but the caller
|
||||||
the values back to the desired type. As the typing is dynamic rather
|
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
|
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 runtime, but all operations will involve a function call.
|
at runtime, but all operations will involve a function call.
|
||||||
@ -561,21 +571,22 @@ go server(1); 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>
|
||||||
Goroutines are (intended to be) cheap.
|
Goroutines are (intended to be) cheap.
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Function literals can be useful with the <code>go</code> statement.
|
Function literals (which Go implements as closures)
|
||||||
|
can be useful with the <code>go</code> statement.
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
var g int // global variable
|
var g int;
|
||||||
go func(i int) {
|
go func(i int) {
|
||||||
s := 0
|
s := 0
|
||||||
for j := 0; j < i; j++ { s += j }
|
for j := 0; j < i; j++ { s += j }
|
||||||
g = s
|
g = s;
|
||||||
} (1000) // Passes argument 1000 to the function literal.
|
} (1000); // Passes argument 1000 to the function literal.
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<h2 id="Channels">Channels</h2>
|
<h2 id="Channels">Channels</h2>
|
||||||
@ -627,7 +638,7 @@ func manager2(ch chan cmd2) {
|
|||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
To use manager2, given a channel to it:
|
To use <code>manager2</code>, given a channel to it:
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
func f4(ch <- chan cmd2) int {
|
func f4(ch <- chan cmd2) int {
|
||||||
|
Loading…
Reference in New Issue
Block a user