1
0
mirror of https://github.com/golang/go synced 2024-11-22 00:04:41 -07:00

Review and update. No major changes, lots of minor tweaks.

R=go-dev
DELTA=176  (39 added, 9 deleted, 128 changed)
OCL=35612
CL=35623
This commit is contained in:
Ian Lance Taylor 2009-10-12 15:43:13 -07:00
parent 9dfe40441e
commit e2854875c5

View File

@ -34,23 +34,25 @@ There is more <a href="./">documentation about go</a>.
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, rather than arrays. This is discussed further
below.
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 change once they
<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>Processes, and communication channels between them, are provided by
the language. This is discussed further below.
<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, channels, and slices, all described further below)
<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.
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
@ -97,7 +99,7 @@ of the object being declared. The keyword is one of <code>var</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 begin declared; see
the discussion of interfaces.
the <a href="#Interfaces">discussion of interfaces</a>.
<p>
You can also use a keyword followed by a series of declarations in
@ -108,7 +110,7 @@ var (i int; m float)
</pre>
<p>
When declaring a function, you must 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
and provide others. You may group several names with the same type:
@ -174,24 +176,15 @@ always <em>permitted</em> at
the end of a statement, so you can continue using them as in C++.
<p>
Go treats semicolons as separators, not terminators. Moreover,
a semicolon
is not required after a curly brace ending a type declaration (e.g.,
<code>var s struct {}</code>) or a block. Semicolons are never required at the
top level of a file (between global declarations). However, they are
always <em>permitted</em> at
the end of a statement, so you can continue using them as in C++.
<p>
When using a pointer, you use <code>.</code> instead of <code>-&gt;</code>.
Thus syntactically
speaking there is no difference between a structure and a pointer to a
structure.
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 my_struct struct { i int }
var v9 my_struct; // v9 has structure type
var p9 *my_struct; // p9 is a pointer to a structure
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>
@ -238,10 +231,10 @@ 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;
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 - 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>.
<pre>
@ -254,6 +247,15 @@ 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>
@ -292,8 +294,11 @@ const ( red = iota; blue; green ) // red == 0, blue == 1, green == 2
<h2 id="Slices">Slices</h2>
<p>
A slice is a pointer to an array, a length, and a capacity. Slices support
the <code>[]</code> operator to access elements. The builtin
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.
@ -383,82 +388,100 @@ entirely separate from the interface itself.
<p>
A method looks like an ordinary function definition, except that it
has a receiver. The receiver is similar to the <code>this</code> pointer in a
C++ class method.
has a <em>receiver</em>. The receiver is similar to
the <code>this</code> pointer in a C++ class method.
<pre>
type my_type struct { i int }
func (p *my_type) get() int { return p.i }
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>my_type</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.
<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 my_interface interface {
type myInterface interface {
get() int;
set(i int);
}
</pre>
<p>
we can make <code>my_type</code> satisfy the interface by additionally writing
we can make <code>myType</code> satisfy the interface by additionally writing
<pre>
func (p *my_type) set(i int) { p.i = i }
func (p *myType) set(i int) { p.i = i }
</pre>
<p>
Now any function which takes <code>my_interface</code> as a parameter
Now any function which takes <code>myInterface</code> as a parameter
will accept a
variable of type <code>*my_type</code>.
variable of type <code>*myType</code>.
<pre>
func get_and_set(x my_interface);
func getAndSet(x myInterface);
func f1() {
var p my_type;
get_and_set(&amp;p);
var p myType;
getAndSet(&amp;p);
}
</pre>
<p>
In other words, if we view <code>my_interface</code> as a C++ pure abstract
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>*my_type</code> made <code>*my_type</code> automatically
inherit from <code>my_interface</code>. A type may satisfy multiple interfaces.
<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 my_child_type struct { my_type; j int }
func (p *my_child_type) get() int { p.j++; return (&amp;p.my_type).get() }
type myChildType struct { myType; j int }
func (p *myChildType) get() int { p.j++; return (&amp;p.myType).get() }
</pre>
<p>
This effectively implements <code>my_child_type</code> as a child of
<code>my_type</code>.
This effectively implements <code>myChildType</code> as a child of
<code>myType</code>.
<pre>
func f2() {
var p my_child_type;
get_and_set(&amp;p)
var p myChildType;
getAndSet(&amp;p)
}
</pre>
<p>
The <code>set</code> method is effectively inherited from
<code>my_child_type</code>, because
<code>myChildType</code>, because
methods associated with the anonymous type are promoted to become methods
of the enclosing type. In this case, because <code>my_child_type</code> has an
anonymous field of type <code>my_type</code>, the methods of
<code>my_type</code> also become methods of <code>my_child_type</code>.
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.
@ -478,23 +501,23 @@ at runtime, like C++ <code>dynamic_cast</code>. Unlike
not need to be any declared relationship between the two interfaces.
<pre>
type my_compare_interface interface {
type myCompareInterface interface {
print();
}
func f3(x my_interface) {
x.(my_compare_interface).print()
func f3(x myInterface) {
x.(myCompareInterface).print()
}
</pre>
<p>
The conversion to <code>my_compare_interface</code> is entirely dynamic.
The conversion to <code>myCompareInterface</code> is entirely dynamic.
It will
work as long as the underlying type of x (the "dynamic type") defines
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, e.g.,
programming similar to templates in C++. This is done by
manipulating values of the minimal interface.
<pre>
@ -517,12 +540,19 @@ type iterator interface {
}
</pre>
<h2 id="Processes">Processes</h2>
<h2 id="Goroutines">Goroutines</h2>
<p>
Go permits starting a new process (a "goroutine") using the <code>go</code>
statement. The go statement runs a function in a different process.
All processes in a single program share the same address space.
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) } }
@ -534,7 +564,7 @@ go server(1); go server(2);
function is equivalent to a C++ <code>while (true)</code> loop).
<p>
Processes are (intended to be) cheap.
Goroutines are (intended to be) cheap.
<p>
Function literals can be useful with the <code>go</code> statement.
@ -551,7 +581,7 @@ go func(i int) {
<h2 id="Channels">Channels</h2>
<p>
Channels are used to communicate between processes. Any value may be
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
@ -561,7 +591,7 @@ functions, channels are passed by reference.
<p>
The Go library provides mutexes, but you can also use
a single process 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
single value.
@ -579,9 +609,9 @@ func manager(ch chan cmd) {
<p>
In that example the same channel is used for input and output. This
means that if two processes try to retrieve the value at the same
time, the first process may read the response which was triggered by
the second process's request. In simple cases that is fine. For more
means that if two goroutines try to retrieve the value at the same
time, the first goroutine may read the response which was triggered by
the second goroutine's request. In simple cases that is fine. For more
complex cases, pass in a channel.
<pre>
@ -601,9 +631,9 @@ To use manager2, given a channel to it:
<pre>
func f4(ch &lt;- chan cmd2) int {
my_ch := make(chan int);
c := cmd2 { true, 0, my_ch }; // Composite literal syntax.
myCh := make(chan int);
c := cmd2{ true, 0, myCh }; // Composite literal syntax.
ch &lt;- c;
return &lt;- my_ch;
return &lt;- myCh;
}
</pre>