are intended to serve not
only as the core library but also as examples of how to
use the language.
+Moreover, many of the packages contain working, self-contained
+executable examples you can run directly from the
+<a href="http://golang.org">golang.org</a> web site, such as
+<a href="http://golang.org/pkg/strings/#example_Map">this one</a> (click
+on the word "Example" to open it up).
If you have a question about how to approach a problem or how something
-might be implemented, they can provide answers, ideas and
+might be implemented, the documentation, code and examples in the
+library can provide answers, ideas and
background.
</p>
<p>
-Some formatting details remain. Very briefly,
+Some formatting details remain. Very briefly:
</p>
<dl>
</dd>
<dt>Parentheses</dt>
<dd>
- Go needs fewer parentheses: control structures (<code>if</code>,
+ Go needs fewer parentheses than C and Java: control structures (<code>if</code>,
<code>for</code>, <code>switch</code>) do not have parentheses in
their syntax.
Also, the operator precedence hierarchy is shorter and clearer, so
<pre>
x<<8 + y<<16
</pre>
- means what the spacing implies.
+ means what the spacing implies, unlike in the other languages.
</dd>
</dl>
Go provides C-style <code>/* */</code> block comments
and C++-style <code>//</code> line comments.
Line comments are the norm;
-block comments appear mostly as package comments and
-are also useful to disable large swaths of code.
+block comments appear mostly as package comments, but
+are useful within an expression or to disable large swaths of code.
</p>
<p>
The comments are uninterpreted plain text, so HTML and other
annotations such as <code>_this_</code> will reproduce <i>verbatim</i> and should
not be used.
+One adjustment <code>godoc</code> does do is to display indented
+text in a fixed-width font, suitable for program snippets.
+The package comment for the
+<a href="http://golang.org/pkg/fmt/"><code>fmt</code> package</a> uses this to good effect.
+</p>
+
+<p>
Depending on the context, <code>godoc</code> might not even
reformat comments, so make sure they look good straight up:
use correct spelling, punctuation, and sentence structure,
func Compile(str string) (regexp *Regexp, err error) {
</pre>
+<p>
+If the name always begins the comment, the output of <code>godoc</code>
+can usefully be run through <code>grep</code>.
+Imagine you couldn't remember the name "Compile" but were looking for
+the parsing function for regular expressions, so you ran
+the command,
+</p>
+
+<pre>
+$ godoc regexp | grep parse
+</pre>
+
+<p>
+If all the doc comments in the package began, "This function...", <code>grep</code>
+wouldn't help you remember the name. But because the package starts each
+doc comment with the name, you'd see something like this,
+which recalls the word you're looking for.
+</p>
+
+<pre>
+$ godoc regexp | grep parse
+ Compile parses a regular expression and returns, if successful, a Regexp
+ parsed. It simplifies safe initialization of global variables holding
+ cannot be parsed. It simplifies safe initialization of global variables
+$
+</pre>
+
<p>
Go's declaration syntax allows grouping of declarations.
A single doc comment can introduce a group of related constants or variables.
<p>
Names are as important in Go as in any other language.
-In some cases they even have semantic effect: for instance,
+They even have semantic effect:
the visibility of a name outside a package is determined by whether its
first character is upper case.
It's therefore worth spending a little time talking about naming conventions
</p>
<p>
-The importer of a package will use the name to refer to its contents
-(the <code>import .</code> notation is intended mostly for tests and other
-unusual situations and should be avoided unless necessary),
+The importer of a package will use the name to refer to its contents.
so exported names in the package can use that fact
to avoid stutter.
+(Don't use the <code>import .</code> notation, which can simplify
+tests that must run outside the package they are testing, but should otherwise be avoided.)
For instance, the buffered reader type in the <code>bufio</code> package is called <code>Reader</code>,
not <code>BufReader</code>, because users see it as <code>bufio.Reader</code>,
which is a clear, concise name.
<code>once.Do(setup)</code> reads well and would not be improved by
writing <code>once.DoOrWaitUntilDone(setup)</code>.
Long names don't automatically make things more readable.
-If the name represents something intricate or subtle, it's usually better
-to write a helpful doc comment than to attempt to put all the information
-into the name.
+A helpful doc comment can often be more valuable than an extra long name.
</p>
<h3 id="Getters">Getters</h3>
<h2 id="semicolons">Semicolons</h2>
<p>
-Like C, Go's formal grammar uses semicolons to terminate statements;
-unlike C, those semicolons do not appear in the source.
+Like C, Go's formal grammar uses semicolons to terminate statements,
+but unlike in C, those semicolons do not appear in the source.
Instead the lexer uses a simple rule to insert semicolons automatically
as it scans, so the input text is mostly free of them.
</p>
</p>
<p>
-One caveat. You should never put the opening brace of a
+One consequence of the semicolon insertion rules
+is that you cannot put the opening brace of a
control structure (<code>if</code>, <code>for</code>, <code>switch</code>,
or <code>select</code>) on the next line. If you do, a semicolon
will be inserted before the brace, which could cause unwanted
</pre>
-<h3 id="redeclaration">Redeclaration</h3>
+<h3 id="redeclaration">Redeclaration and reassignment</h3>
<p>
An aside: The last example in the previous section demonstrates a detail of how the
<ul>
<li>this declaration is in the same scope as the existing declaration of <code>v</code>
-(if <code>v</code> is already declared in an outer scope, the declaration will create a new variable),</li>
+(if <code>v</code> is already declared in an outer scope, the declaration will create a new variable §),</li>
<li>the corresponding value in the initialization is assignable to <code>v</code>, and</li>
<li>there is at least one other variable in the declaration that is being declared anew.</li>
</ul>
You'll see it used often.
</p>
+<p>
+§ It's worth noting here that in Go the scope of function parameters and return values
+is the same as the function body, even though they appear lexically outside the braces
+that enclose the body.
+</p>
+
<h3 id="for">For</h3>
<p>
</p>
<pre>
for key := range m {
- if expired(key) {
+ if key.expired() {
delete(m, key)
}
}
<p>
For strings, the <code>range</code> does more work for you, breaking out individual
-Unicode characters by parsing the UTF-8.
+Unicode code points by parsing the UTF-8.
Erroneous encodings consume one byte and produce the
replacement rune U+FFFD. The loop
</p>
<pre>
-for pos, char := range "日本語" {
- fmt.Printf("character %c starts at byte position %d\n", char, pos)
+for pos, char := range "日本\x80語" { // \x80 is an illegal UTF-8 encoding
+ fmt.Printf("character %#U starts at byte position %d\n", char, pos)
}
</pre>
<p>
prints
</p>
<pre>
-character 日 starts at byte position 0
-character 本 starts at byte position 3
-character 語 starts at byte position 6
+character U+65E5 '日' starts at byte position 0
+character U+672C '本' starts at byte position 3
+character U+FFFD '�' starts at byte position 6
+character U+8A9E '語' starts at byte position 7
</pre>
<p>
Finally, Go has no comma operator and <code>++</code> and <code>--</code>
are statements not expressions.
Thus if you want to run multiple variables in a <code>for</code>
-you should use parallel assignment.
+you should use parallel assignment (although that precludes <code>++</code> and <code>--</code>).
</p>
<pre>
// Reverse a
assertion with the keyword <code>type</code> inside the parentheses.
If the switch declares a variable in the expression, the variable will
have the corresponding type in each clause.
+It's also idiomatic to reuse the name in such cases, in effect declaring
+a new variable with the same name but a different type in each case.
</p>
<pre>
-switch t := interfaceValue.(type) {
+var t interface{}
+t = functionOfSomeType()
+switch t := t.(type) {
default:
- fmt.Printf("unexpected type %T", t) // %T prints type
+ fmt.Printf("unexpected type %T", t) // %T prints whatever type t has
case bool:
- fmt.Printf("boolean %t\n", t)
+ fmt.Printf("boolean %t\n", t) // t has type bool
case int:
- fmt.Printf("integer %d\n", t)
+ fmt.Printf("integer %d\n", t) // t has type int
case *bool:
- fmt.Printf("pointer to boolean %t\n", *t)
+ fmt.Printf("pointer to boolean %t\n", *t) // t has type *bool
case *int:
- fmt.Printf("pointer to integer %d\n", *t)
+ fmt.Printf("pointer to integer %d\n", *t) // t has type *int
}
</pre>