From: Rob Pike Date: Fri, 1 Mar 2013 00:57:55 +0000 (-0800) Subject: doc/effective_go.html: minor updates, part 1 X-Git-Tag: go1.1rc2~762 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=6bfec725cfaa8c57f5a35c3f2a27880d808fe102;p=gostls13.git doc/effective_go.html: minor updates, part 1 R=golang-dev, adg CC=golang-dev https://golang.org/cl/7454044 --- diff --git a/doc/effective_go.html b/doc/effective_go.html index 4bc92870ac..e02694add1 100644 --- a/doc/effective_go.html +++ b/doc/effective_go.html @@ -41,8 +41,14 @@ The Go package sources 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 +golang.org web site, such as +this one (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.

@@ -108,7 +114,7 @@ All Go code in the standard packages has been formatted with gofmt.

-Some formatting details remain. Very briefly, +Some formatting details remain. Very briefly:

@@ -123,14 +129,14 @@ Some formatting details remain. Very briefly,
Parentheses
- Go needs fewer parentheses: control structures (if, + Go needs fewer parentheses than C and Java: control structures (if, for, switch) do not have parentheses in their syntax. Also, the operator precedence hierarchy is shorter and clearer, so
 x<<8 + y<<16
 
- means what the spacing implies. + means what the spacing implies, unlike in the other languages.
@@ -140,8 +146,8 @@ x<<8 + y<<16 Go provides C-style /* */ block comments and C++-style // 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.

@@ -205,6 +211,13 @@ takes care of that. The comments are uninterpreted plain text, so HTML and other annotations such as _this_ will reproduce verbatim and should not be used. +One adjustment godoc does do is to display indented +text in a fixed-width font, suitable for program snippets. +The package comment for the +fmt package uses this to good effect. +

+ +

Depending on the context, godoc might not even reformat comments, so make sure they look good straight up: use correct spelling, punctuation, and sentence structure, @@ -231,6 +244,33 @@ starts with the name being declared. func Compile(str string) (regexp *Regexp, err error) { +

+If the name always begins the comment, the output of godoc +can usefully be run through grep. +Imagine you couldn't remember the name "Compile" but were looking for +the parsing function for regular expressions, so you ran +the command, +

+ +
+$ godoc regexp | grep parse
+
+ +

+If all the doc comments in the package began, "This function...", grep +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. +

+ +
+$ 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
+$
+
+

Go's declaration syntax allows grouping of declarations. A single doc comment can introduce a group of related constants or variables. @@ -265,7 +305,7 @@ var (

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 @@ -310,11 +350,11 @@ not encoding_base64 and not encodingBase64.

-The importer of a package will use the name to refer to its contents -(the import . 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 import . 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 bufio package is called Reader, not BufReader, because users see it as bufio.Reader, which is a clear, concise name. @@ -335,9 +375,7 @@ Another short example is once.Do; once.Do(setup) reads well and would not be improved by writing once.DoOrWaitUntilDone(setup). 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.

Getters

@@ -394,8 +432,8 @@ multiword names.

Semicolons

-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.

@@ -431,7 +469,8 @@ statements on a line, should you write code that way.

-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 (if, for, switch, or select) on the next line. If you do, a semicolon will be inserted before the brace, which could cause unwanted @@ -540,7 +579,7 @@ codeUsing(f, d) -

Redeclaration

+

Redeclaration and reassignment

An aside: The last example in the previous section demonstrates a detail of how the @@ -577,7 +616,7 @@ if it has already been declared, provided:

@@ -589,6 +628,12 @@ in a long if-else chain. You'll see it used often.

+

+§ 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. +

+

For

@@ -634,7 +679,7 @@ If you only need the first item in the range (the key or index), drop the second

 for key := range m {
-    if expired(key) {
+    if key.expired() {
         delete(m, key)
     }
 }
@@ -652,29 +697,30 @@ for _, value := range array {
 
 

For strings, the range 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

-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)
 }
 

prints

-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
 

Finally, Go has no comma operator and ++ and -- are statements not expressions. Thus if you want to run multiple variables in a for -you should use parallel assignment. +you should use parallel assignment (although that precludes ++ and --).

 // Reverse a
@@ -757,19 +803,23 @@ variable.  Such a type switch uses the syntax of a type
 assertion with the keyword type 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.
 

-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
 }