mirror of
https://github.com/golang/go
synced 2024-11-22 06:54:39 -07:00
A step towards "externalizing" some Go docs.
+ style sheet: like code.google.com but less feature-ful + JS with table-of-contents generation + tweaked go_spec.html and go_mem.html to use new style+JS + static-HTML-ified a few other Go docs: + static HTML versions of some wiki pages (which I'll turn into links to these pages). A notable thing that is _not_ in this changelist: any change to the godoc tool or whatever thing generates http://go/godoc R=r APPROVED=r DELTA=2472 (2307 added, 113 deleted, 52 changed) OCL=34644 CL=34728
This commit is contained in:
parent
229e976163
commit
698c6c00a0
673
doc/go_for_cpp_programmers.html
Normal file
673
doc/go_for_cpp_programmers.html
Normal file
@ -0,0 +1,673 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/html4/transitional.dtd">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
To convert <h2>Foo</h2> into <h2 id="Foo">Foo</h2>
|
||||||
|
and convert §Foo into §<a href="#Foo">Foo</a>:
|
||||||
|
|
||||||
|
Edit ,s/<(h.)>(.*)(<\/h.>)/<\1 id="\2">\2\3/g
|
||||||
|
Edit ,x g/id="/ x/id="[^"]+"/ s/ /_/g
|
||||||
|
Edit ,s/§([^),.]+)/§<a href="#\1">\1<\/a>/g
|
||||||
|
Edit ,x/href="#[^"]+"/ s/ /_/g
|
||||||
|
-->
|
||||||
|
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
||||||
|
<title>Go For C++ Programmers</title>
|
||||||
|
|
||||||
|
<link rel="stylesheet" type="text/css" href="style.css">
|
||||||
|
<script type="text/javascript" src="godocs.js"></script>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div id="topnav">
|
||||||
|
<table summary=""><tr>
|
||||||
|
<td id="headerImage">
|
||||||
|
<a href="./"><img src="./logo_blue.png" height="44" width="120" alt="Go Home Page" style="border:0" /></a>
|
||||||
|
</td>
|
||||||
|
<td id="headerDocSetTitle">The Go Programming Language</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="linkList">
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li class="navhead">Related Guides</li>
|
||||||
|
<li><a href="go_tutorial.html">Tutorial</a></li>
|
||||||
|
<li class="blank"> </li>
|
||||||
|
<li class="navhead">Other Resources</li>
|
||||||
|
<li><a href="./">Go Docs</a></li>
|
||||||
|
<li><a href="/pkg">Library documentation</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="content">
|
||||||
|
|
||||||
|
<h1 id="The_Go_Programming_Language_Specification">Go For C++ Programmers</h1>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Go is a systems programming language intended as an alternative to 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>.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
For a detailed description of the Go language, see the
|
||||||
|
<a href="go_spec.html">Go spec</a>.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
There is more <a href="./">documentation about go</a>.
|
||||||
|
|
||||||
|
|
||||||
|
<!-- The Table of Contents is automatically inserted in this <div>.
|
||||||
|
Do not delete this <div>. -->
|
||||||
|
<div id="nav"></div>
|
||||||
|
|
||||||
|
<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 currently possible)
|
||||||
|
to explicitly release memory. The garbage collection is (intended to be)
|
||||||
|
incremental and highly efficient on modern processors.
|
||||||
|
|
||||||
|
<li>Go supports pointers, but does not support 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, rather than arrays. This is discussed further
|
||||||
|
below.
|
||||||
|
|
||||||
|
<li>Strings are provided by the language. They may not change 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>Certain types (maps, channels, and slices, all 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.
|
||||||
|
|
||||||
|
<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 which starts with an
|
||||||
|
uppercase letter, than 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 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; // approximately const std::string v2;
|
||||||
|
var v3 [10]int; // int v3[10];
|
||||||
|
var v4 []int; // approximately int* v4;
|
||||||
|
var v5 struct { f int }; // struct { int f; } v5;
|
||||||
|
var v6 *int; // int* v6; // but no pointer arithmetic
|
||||||
|
var v7 map[string]int; // approximately unordered_map<string, int>* v7;
|
||||||
|
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 begin declared; see
|
||||||
|
the discussion of interfaces.
|
||||||
|
|
||||||
|
<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 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);
|
||||||
|
</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, the type must be specified.
|
||||||
|
In that case it will be
|
||||||
|
implicitly initialized to 0 (or nil, or whatever). There are no
|
||||||
|
uninitialized variables in Go.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Within a function, a simple 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, indicating by a list in
|
||||||
|
parentheses.
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
func f() (i int, j int);
|
||||||
|
v1, v2 = f();
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<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>
|
||||||
|
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>-></code>.
|
||||||
|
Thus syntactically
|
||||||
|
speaking there is no difference between a structure and a pointer to a
|
||||||
|
structure.
|
||||||
|
|
||||||
|
<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
|
||||||
|
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
|
||||||
|
if (a < b) f(); // 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: 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>.
|
||||||
|
|
||||||
|
<h2 id="Constants">Constants </h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
In Go integer and floating-point constants have so-called ideal types.
|
||||||
|
This applies even to constants named with a <code>const</code> declaration,
|
||||||
|
if no
|
||||||
|
type is given in the declaration. An ideal type becomes concrete when
|
||||||
|
it is actually used. This permits constants to be used relatively
|
||||||
|
freely without requiring general implicit type conversion.
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
var a uint; f(a + 1) // Ideal type of "1" becomes "uint".
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The language does not impose any limits on the size of an abstract
|
||||||
|
integer constant or constant expression. A limit is only applied when
|
||||||
|
a constant expression 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; blue; green ) // red == 0, blue == 1, green == 2
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<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
|
||||||
|
<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 at index
|
||||||
|
<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
|
||||||
|
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 a pointer to an
|
||||||
|
array to a
|
||||||
|
variable of slice type; given <code>var s []int; var a[10] int</code>,
|
||||||
|
<code>s = &a</code> is more or
|
||||||
|
less the same as <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 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.
|
||||||
|
|
||||||
|
<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> returns a new object of type
|
||||||
|
<code>*int</code>,
|
||||||
|
allocated on the heap and initialized with the value <code>0</code>.
|
||||||
|
Unlike 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 is the
|
||||||
|
buffering capacity of the channel.
|
||||||
|
|
||||||
|
<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 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 receiver. 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 }
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
This declares a method <code>get</code> associated with <code>my_type</code>.
|
||||||
|
The receiver is named <code>p</code> in the body of the function.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Given this interface:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
type my_interface interface {
|
||||||
|
get() int;
|
||||||
|
set(i int);
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
we can make <code>my_type</code> satisfy the interface by additionally writing
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
func (p *my_type) set(i int) { p.i = i }
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Now any function which takes <code>my_interface</code> as a parameter
|
||||||
|
will accept a
|
||||||
|
variable of type <code>*my_type</code>.
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
func get_and_set(x my_interface);
|
||||||
|
func f1() {
|
||||||
|
var p my_type;
|
||||||
|
get_and_set(&p);
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
In other words, if we view <code>my_interface</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.
|
||||||
|
|
||||||
|
<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 (&p.my_type).get() }
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
This effectively implements <code>my_child_type</code> as a child of
|
||||||
|
<code>my_type</code>.
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
func f2() {
|
||||||
|
var p my_child_type;
|
||||||
|
get_and_set(&p)
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The <code>set</code> method is effectively inherited from
|
||||||
|
<code>my_child_type</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>.
|
||||||
|
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 parent
|
||||||
|
method is called, it receives a pointer to the field in the child class.
|
||||||
|
If the parent method calls some other method on its argument, it will call
|
||||||
|
the method associated with the parent class, not the method associated with
|
||||||
|
the child class. In other words, methods 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. This conversion 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 my_compare_interface interface {
|
||||||
|
print();
|
||||||
|
}
|
||||||
|
func f3(x my_interface) {
|
||||||
|
x.(my_compare_interface).print()
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The conversion to <code>my_compare_interface</code> is entirely dynamic.
|
||||||
|
It will
|
||||||
|
work as long as the underlying type of x (the "dynamic type") 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.,
|
||||||
|
manipulating values of the minimal interface.
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
type Any interface { }
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Containers may be written in terms of <code>Any</code>, and the caller may cast
|
||||||
|
the values back to the desired 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="Processes">Processes</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.
|
||||||
|
|
||||||
|
<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>
|
||||||
|
Processes are (intended to be) cheap.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Function literals can be useful with the <code>go</code> statement.
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
var g int // global variable
|
||||||
|
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 processes. 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 process 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
|
||||||
|
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
|
||||||
|
complex cases, 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 manager2, given a channel to it:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
func f4(ch <- chan cmd2) int {
|
||||||
|
my_ch := make(chan int);
|
||||||
|
c := cmd2 { true, 0, my_ch }; // Composite literal syntax.
|
||||||
|
ch <- c;
|
||||||
|
return <- my_ch;
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="footer">
|
||||||
|
<p>Except as noted, this content is
|
||||||
|
licensed under <a href="http://creativecommons.org/licenses/by/3.0/">
|
||||||
|
Creative Commons Attribution 3.0</a>.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -1,5 +1,57 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/html4/transitional.dtd">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
|
||||||
<h1>The Go memory model</h1>
|
<!--
|
||||||
|
To convert <h2>Foo</h2> into <h2 id="Foo">Foo</h2>
|
||||||
|
and convert §Foo into §<a href="#Foo">Foo</a>:
|
||||||
|
|
||||||
|
Edit ,s/<(h.)>(.*)(<\/h.>)/<\1 id="\2">\2\3/g
|
||||||
|
Edit ,x g/id="/ x/id="[^"]+"/ s/ /_/g
|
||||||
|
Edit ,s/§([^),.]+)/§<a href="#\1">\1<\/a>/g
|
||||||
|
Edit ,x/href="#[^"]+"/ s/ /_/g
|
||||||
|
-->
|
||||||
|
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
||||||
|
<title>The Go Memory Model</title>
|
||||||
|
|
||||||
|
<link rel="stylesheet" type="text/css" href="style.css">
|
||||||
|
<script type="text/javascript" src="godocs.js"></script>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div id="topnav">
|
||||||
|
<table summary=""><tr>
|
||||||
|
<td id="headerImage">
|
||||||
|
<a href="./"><img src="./logo_blue.png" height="44" width="120" alt="Go Home Page" style="border:0" /></a>
|
||||||
|
</td>
|
||||||
|
<td id="headerDocSetTitle">The Go Progrmming Language</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="linkList">
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li class="navhead">Related Guides</li>
|
||||||
|
<li><a href="go_spec.html">Language Specification</a></li>
|
||||||
|
<li class="blank"> </li>
|
||||||
|
<li class="navhead">Other Resources</li>
|
||||||
|
<li><a href="./">Go Docs</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="content">
|
||||||
|
|
||||||
|
<h1 id="The_Go_Programming_Language_Specification">The Go Memory Model</h1>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- The Table of Contents is automatically inserted in this <div>.
|
||||||
|
Do not delete this <div>. -->
|
||||||
|
<div id="nav"></div>
|
||||||
|
|
||||||
<h2>Introduction</h2>
|
<h2>Introduction</h2>
|
||||||
|
|
||||||
@ -453,6 +505,15 @@ In all these examples, the solution is the same:
|
|||||||
use explicit synchronization.
|
use explicit synchronization.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="footer">
|
||||||
|
<p>Except as noted, this content is
|
||||||
|
licensed under <a href="http://creativecommons.org/licenses/by/3.0/">
|
||||||
|
Creative Commons Attribution 3.0</a>.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
@ -1,4 +1,60 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/html4/transitional.dtd">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
To convert <h2>Foo</h2> into <h2 id="Foo">Foo</h2>
|
||||||
|
and convert §Foo into §<a href="#Foo">Foo</a>:
|
||||||
|
|
||||||
|
Edit ,s/<(h.)>(.*)(<\/h.>)/<\1 id="\2">\2\3/g
|
||||||
|
Edit ,x g/id="/ x/id="[^"]+"/ s/ /_/g
|
||||||
|
Edit ,s/§([^),.]+)/§<a href="#\1">\1<\/a>/g
|
||||||
|
Edit ,x/href="#[^"]+"/ s/ /_/g
|
||||||
|
-->
|
||||||
|
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
||||||
|
<title>The Go Programming Language Specification</title>
|
||||||
|
|
||||||
|
<link rel="stylesheet" type="text/css" href="style.css">
|
||||||
|
<script type="text/javascript" src="godocs.js"></script>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div id="topnav">
|
||||||
|
<table summary=""><tr>
|
||||||
|
<td id="headerImage">
|
||||||
|
<a href="./"><img src="./logo_blue.png" height="44" width="120" alt="Go Home Page" style="border:0" /></a>
|
||||||
|
</td>
|
||||||
|
<td id="headerDocSetTitle">The Go Programming Language</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="linkList">
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li class="navhead">Related Guides</li>
|
||||||
|
<li><a href="go_tutorial.html">Tutorial</a></li>
|
||||||
|
<li><a href="go_for_cpp_programmers.html">Go for C++ Programmers</a></li>
|
||||||
|
<li class="blank"> </li>
|
||||||
|
<li class="navhead">Other Resources</li>
|
||||||
|
<li><a href="./">Go Docs</a></li>
|
||||||
|
<li><a href="/pkg">Library documentation</a></li>
|
||||||
|
<li><a href="go_faq.html">FAQ</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="content">
|
||||||
|
|
||||||
|
<h1 id="The_Go_Programming_Language_Specification">The Go Programming Language Specification</h1>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- The Table of Contents is automatically inserted in this <div>.
|
||||||
|
Do not delete this <div>. -->
|
||||||
|
<div id="nav"></div>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Open issues:
|
Open issues:
|
||||||
@ -47,7 +103,7 @@ compile/link model to generate executable binaries.
|
|||||||
The grammar is compact and regular, allowing for easy analysis by
|
The grammar is compact and regular, allowing for easy analysis by
|
||||||
automatic tools such as integrated development environments.
|
automatic tools such as integrated development environments.
|
||||||
</p>
|
</p>
|
||||||
<hr/>
|
|
||||||
<h2 id="Notation">Notation</h2>
|
<h2 id="Notation">Notation</h2>
|
||||||
<p>
|
<p>
|
||||||
The syntax is specified using Extended Backus-Naur Form (EBNF):
|
The syntax is specified using Extended Backus-Naur Form (EBNF):
|
||||||
@ -85,8 +141,6 @@ The form <code>a ... b</code> represents the set of characters from
|
|||||||
<code>a</code> through <code>b</code> as alternatives.
|
<code>a</code> through <code>b</code> as alternatives.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<hr/>
|
|
||||||
|
|
||||||
<h2 id="Source_code_representation">Source code representation</h2>
|
<h2 id="Source_code_representation">Source code representation</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -131,7 +185,6 @@ decimal_digit = "0" ... "9" .
|
|||||||
octal_digit = "0" ... "7" .
|
octal_digit = "0" ... "7" .
|
||||||
hex_digit = "0" ... "9" | "A" ... "F" | "a" ... "f" .
|
hex_digit = "0" ... "9" | "A" ... "F" | "a" ... "f" .
|
||||||
</pre>
|
</pre>
|
||||||
<hr/>
|
|
||||||
|
|
||||||
<h2 id="Lexical_elements">Lexical elements</h2>
|
<h2 id="Lexical_elements">Lexical elements</h2>
|
||||||
|
|
||||||
@ -432,7 +485,6 @@ an error if placed in a character literal (it is not a single code
|
|||||||
point), and will appear as two code points if placed in a string
|
point), and will appear as two code points if placed in a string
|
||||||
literal.
|
literal.
|
||||||
</p>
|
</p>
|
||||||
<hr/>
|
|
||||||
|
|
||||||
<h3 id="Boolean_literals">Boolean literals</h3>
|
<h3 id="Boolean_literals">Boolean literals</h3>
|
||||||
|
|
||||||
@ -1240,8 +1292,6 @@ Interface values may be compared if they have compatible static types.
|
|||||||
They will be equal only if they have the same dynamic type and the underlying values are equal.
|
They will be equal only if they have the same dynamic type and the underlying values are equal.
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<hr/>
|
|
||||||
|
|
||||||
|
|
||||||
<h2 id="Blocks">Blocks</h2>
|
<h2 id="Blocks">Blocks</h2>
|
||||||
|
|
||||||
@ -3032,8 +3082,6 @@ and indexing of <code>x</code> and the evaluation
|
|||||||
of <code>y</code> is not specified.
|
of <code>y</code> is not specified.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<hr/>
|
|
||||||
|
|
||||||
<h2 id="Statements">Statements</h2>
|
<h2 id="Statements">Statements</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -3851,8 +3899,6 @@ for i := 0; i <= 3; i++ {
|
|||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<hr/>
|
|
||||||
|
|
||||||
<h2 id="Predeclared_functions">Predeclared functions</h2>
|
<h2 id="Predeclared_functions">Predeclared functions</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li>cap
|
<li>cap
|
||||||
@ -4065,8 +4111,6 @@ m := make(map[string] int, 100); # map with initial space for 100 elements
|
|||||||
<font color=red>TODO: Need syntax that permits a type as first argument for built-ins.</font>
|
<font color=red>TODO: Need syntax that permits a type as first argument for built-ins.</font>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<hr/>
|
|
||||||
|
|
||||||
<h2 id="Packages">Packages</h2>
|
<h2 id="Packages">Packages</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -4235,8 +4279,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<hr/>
|
|
||||||
|
|
||||||
<h2 id="Program_initialization_and_execution">Program initialization and execution</h2>
|
<h2 id="Program_initialization_and_execution">Program initialization and execution</h2>
|
||||||
|
|
||||||
<h3 id="The_zero_value">The zero value</h3>
|
<h3 id="The_zero_value">The zero value</h3>
|
||||||
@ -4367,8 +4409,6 @@ Implementation restriction: The compiler assumes package <code>main</code>
|
|||||||
is not imported by any other package.
|
is not imported by any other package.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<hr/>
|
|
||||||
|
|
||||||
<h2 id="System_considerations">System considerations</h2>
|
<h2 id="System_considerations">System considerations</h2>
|
||||||
|
|
||||||
<h3 id="Package_unsafe">Package <code>unsafe</code></h3>
|
<h3 id="Package_unsafe">Package <code>unsafe</code></h3>
|
||||||
@ -4480,8 +4520,6 @@ The following minimal alignment properties are guaranteed:
|
|||||||
<code>unsafe.Alignof(x[0])</code>, but at least 1.
|
<code>unsafe.Alignof(x[0])</code>, but at least 1.
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<hr/>
|
|
||||||
|
|
||||||
<h2 id="Implementation_differences"><font color=red>Implementation differences - TODO</font></h2>
|
<h2 id="Implementation_differences"><font color=red>Implementation differences - TODO</font></h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li><font color=red>Implementation does not honor the restriction on goto statements and targets (no intervening declarations).</font></li>
|
<li><font color=red>Implementation does not honor the restriction on goto statements and targets (no intervening declarations).</font></li>
|
||||||
@ -4490,5 +4528,12 @@ The following minimal alignment properties are guaranteed:
|
|||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="footer">
|
||||||
|
<p>Except as noted, this content is
|
||||||
|
licensed under <a href="http://creativecommons.org/licenses/by/3.0/">
|
||||||
|
Creative Commons Attribution 3.0</a>.
|
||||||
|
</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
160
doc/godocs.js
Normal file
160
doc/godocs.js
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
// Except as noted, this content is licensed under Creative Commons
|
||||||
|
// Attribution 3.0
|
||||||
|
|
||||||
|
/* A little code to ease navigation of these documents.
|
||||||
|
*
|
||||||
|
* On window load we:
|
||||||
|
* + Generate a table of contents (godocs_generateTOC)
|
||||||
|
* + Add links up to the top of the doc from each section (godocs_addTopLinks)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* We want to do some stuff on page load (after the HTML is rendered).
|
||||||
|
So listen for that:
|
||||||
|
*/
|
||||||
|
if (window.addEventListener){
|
||||||
|
window.addEventListener('load', godocs_onload, false);
|
||||||
|
} else if (elm.attachEvent){
|
||||||
|
window.attachEvent('onload', godocs_onload);
|
||||||
|
}
|
||||||
|
|
||||||
|
function godocs_onload() {
|
||||||
|
godocs_generateTOC();
|
||||||
|
godocs_addTopLinks();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generates a table of contents: looks for h2 and h3 elements and generates
|
||||||
|
* links. "Decorates" the element with id=="nav" with this table of contents.
|
||||||
|
*/
|
||||||
|
function godocs_generateTOC() {
|
||||||
|
var navbar = document.getElementById('nav');
|
||||||
|
if (!navbar) { return; }
|
||||||
|
|
||||||
|
var toc_items = [];
|
||||||
|
|
||||||
|
var i;
|
||||||
|
for (i = 0; i < navbar.parentNode.childNodes.length; i++) {
|
||||||
|
var node = navbar.parentNode.childNodes[i];
|
||||||
|
if ((node.tagName == 'h2') || (node.tagName == 'H2')) {
|
||||||
|
if (!node.id) {
|
||||||
|
node.id = 'tmp_' + i;
|
||||||
|
}
|
||||||
|
var text = godocs_nodeToText(node);
|
||||||
|
if (!text) { continue; }
|
||||||
|
|
||||||
|
var textNode = document.createTextNode(text);
|
||||||
|
|
||||||
|
var link = document.createElement('a');
|
||||||
|
link.href = '#' + node.id;
|
||||||
|
link.appendChild(textNode);
|
||||||
|
|
||||||
|
// Then create the item itself
|
||||||
|
var item = document.createElement('dt');
|
||||||
|
|
||||||
|
item.appendChild(link);
|
||||||
|
toc_items.push(item);
|
||||||
|
}
|
||||||
|
if ((node.tagName == 'h3') || (node.tagName == 'H3')) {
|
||||||
|
if (!node.id) {
|
||||||
|
node.id = 'tmp_' + i;
|
||||||
|
}
|
||||||
|
var text = godocs_nodeToText(node);
|
||||||
|
if (!text) { continue; }
|
||||||
|
|
||||||
|
var textNode = document.createTextNode(text);
|
||||||
|
|
||||||
|
var link = document.createElement('a');
|
||||||
|
link.href = '#' + node.id;
|
||||||
|
link.appendChild(textNode);
|
||||||
|
|
||||||
|
// Then create the item itself
|
||||||
|
var item = document.createElement('dd');
|
||||||
|
|
||||||
|
item.appendChild(link);
|
||||||
|
toc_items.push(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!toc_items.length) { return; }
|
||||||
|
|
||||||
|
var dl1 = document.createElement('dl');
|
||||||
|
var dl2 = document.createElement('dl');
|
||||||
|
|
||||||
|
var split_index = (toc_items.length / 2) + 1;
|
||||||
|
if (split_index < 8) {
|
||||||
|
split_index = toc_items.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < split_index; i++) {
|
||||||
|
dl1.appendChild(toc_items[i]);
|
||||||
|
}
|
||||||
|
for (/* keep using i */; i < toc_items.length; i++) {
|
||||||
|
dl2.appendChild(toc_items[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
var tocTable = document.createElement('table');
|
||||||
|
navbar.appendChild(tocTable);
|
||||||
|
tocTable.className = 'unruled';
|
||||||
|
var tocBody = document.createElement('tbody');
|
||||||
|
tocTable.appendChild(tocBody);
|
||||||
|
|
||||||
|
var tocRow = document.createElement('tr');
|
||||||
|
tocBody.appendChild(tocRow);
|
||||||
|
|
||||||
|
// 1st column
|
||||||
|
var tocCell = document.createElement('td');
|
||||||
|
tocCell.className = 'first';
|
||||||
|
tocRow.appendChild(tocCell);
|
||||||
|
tocCell.appendChild(dl1);
|
||||||
|
|
||||||
|
// 2nd column
|
||||||
|
tocCell = document.createElement('td');
|
||||||
|
tocRow.appendChild(tocCell);
|
||||||
|
tocCell.appendChild(dl2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns the "This sweet header" from <h2>This <i>sweet</i> header</h2>.
|
||||||
|
* Takes a node, returns a string.
|
||||||
|
*/
|
||||||
|
function godocs_nodeToText(node) {
|
||||||
|
var TEXT_NODE = 3; // Defined in Mozilla but not MSIE :(
|
||||||
|
|
||||||
|
var text = '';
|
||||||
|
for (var j = 0; j != node.childNodes.length; j++) {
|
||||||
|
var child = node.childNodes[j];
|
||||||
|
if (child.nodeType == TEXT_NODE) {
|
||||||
|
if (child.nodeValue != '[Top]') { //ok, that's a hack, but it works.
|
||||||
|
text = text + child.nodeValue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
text = text + godocs_nodeToText(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For each H2 heading, add a link up to the #top of the document.
|
||||||
|
* (As part of this: ensure existence of 'top' named anchor link
|
||||||
|
* (theoretically at doc's top).)
|
||||||
|
*/
|
||||||
|
function godocs_addTopLinks() {
|
||||||
|
/* Make sure there's a "top" to link to. */
|
||||||
|
var top = document.getElementById('top');
|
||||||
|
if (!top) {
|
||||||
|
document.body.id = 'top';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!document.getElementsByTagName) return; // no browser support
|
||||||
|
|
||||||
|
var headers = document.getElementsByTagName('h2');
|
||||||
|
|
||||||
|
for (var i = 0; i < headers.length; i++) {
|
||||||
|
var span = document.createElement('span');
|
||||||
|
span.className = 'navtop';
|
||||||
|
var link = document.createElement('a');
|
||||||
|
span.appendChild(link);
|
||||||
|
link.href = '#top';
|
||||||
|
var textNode = document.createTextNode('[Top]');
|
||||||
|
link.appendChild(textNode);
|
||||||
|
headers[i].appendChild(span);
|
||||||
|
}
|
||||||
|
}
|
134
doc/style.css
Normal file
134
doc/style.css
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
code, .code {
|
||||||
|
font-size: 9pt;
|
||||||
|
font-family: Courier, Courier New, monospace;
|
||||||
|
color:#007000;
|
||||||
|
}
|
||||||
|
|
||||||
|
kbd {
|
||||||
|
font-family: Courier, Courier New, monospace;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre.ebnf {
|
||||||
|
background-color: beige;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre.grammar {
|
||||||
|
background-color: beige;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.rule {
|
||||||
|
font-style: italic
|
||||||
|
}
|
||||||
|
|
||||||
|
span.event {
|
||||||
|
font-style: italic
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font: 13px Helvetica, Arial, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
font-family: Helvetica, Arial, sans-serif;
|
||||||
|
margin-bottom: 0.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
background-color: #e5ecf9;
|
||||||
|
margin-top: 2em;
|
||||||
|
border-top:1px solid #36C;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre{
|
||||||
|
font-size: 9pt;
|
||||||
|
background-color: #fafaff;
|
||||||
|
margin: 1em 0 0 0;
|
||||||
|
padding: .99em;
|
||||||
|
line-height: 125%;
|
||||||
|
overflow: auto;
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
padding-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
li pre {
|
||||||
|
margin: 0.5em 0px 1em 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Above this comment, styles meant to help page authors achieve beauty. */
|
||||||
|
/* Below this comment, styles used in the boilerplate-ish parts of pages. */
|
||||||
|
|
||||||
|
div#content {
|
||||||
|
margin-left: 20%;
|
||||||
|
padding: 0 1em 2em 1em;
|
||||||
|
margin-top: -2px;
|
||||||
|
border: 2px solid #e5ecf9;
|
||||||
|
}
|
||||||
|
|
||||||
|
#topnav {
|
||||||
|
margin: 0px;
|
||||||
|
padding: .1em 0px;
|
||||||
|
width: 100%;
|
||||||
|
white-space: nowrap;
|
||||||
|
background-color: #e5ecf9;
|
||||||
|
border-top:1px solid #36C;
|
||||||
|
font: bold large Helvetica, Arial, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#linkList {
|
||||||
|
font: 13px Helvetica, Arial, sans-serif;
|
||||||
|
float: left;
|
||||||
|
width: 20%;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#linkList ul {
|
||||||
|
padding: 1px;
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#linkList li {
|
||||||
|
margin-left: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#linkList li.navhead {
|
||||||
|
font-weight: bold;
|
||||||
|
margin-left: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#nav dl {
|
||||||
|
margin: 0 0.5em 0 0.5em;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navtop {
|
||||||
|
font-size: xx-small;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
#footer {
|
||||||
|
margin: 2em;
|
||||||
|
text-align: center;
|
||||||
|
color: #555;
|
||||||
|
font-size: small;
|
||||||
|
}
|
||||||
|
|
||||||
|
#footer a {
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media print {
|
||||||
|
div#linkList {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.navtop {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
div#content {
|
||||||
|
margin-left: 0px;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user