The Go Language
References
Housekeeping
Formatting
Use gofmt
.
Some general rules
- Tabs are referred. Spaces only if we must.
- Go has no line length limit.
Comments
Go uses C-style block and line comments. Line comments are the norm.
Comments that appear before top-level declarations with no intervening newlines are extracted along with the declaration to serve as explanatory text for them. Use godoc
for this.
Every package should have a /package comment/. For multi-file packages, this needs to be present only in any one file.
Comments don’t need extra formatting. Don’t depend on spacing for alignment.
godoc
displays indented text in a fixed-width font, suitable for program snippets.
Any comment immediately preceding a top-level declaration serves as a doc comment for that declaration. Every exported (capitalized) name in a program snould have a doc comment.
Starting the first line of a doc comment with the name of the item described allows us to use go doc
and run the output through grep
to get something similar to apropos
.
$ go doc -all regexp | grep -i parse
# Searching for a function to parse a regex.
Declarations can be grouped, allowing a single doc comment to introduce a group of related variables.
Names
The visibility of a name outside a package is determined by whether its first character is upper case.
When a package is imported, the package name becomes an accessor for contents. By convention, package names are lower case, single-word names.
Another convention is that the package name is the base name of its source directory.
- Getters and Setters
- For a field called
owner
(lower case unexported), the getter method should be calledOwner
(upper case, exported). The setter could be calledSetOwner
. - Interface Names
- By convention, one-method interfaces are named by the method name plus an -er suffic or similar modification to construct an /agent/ noun: Reader, Writer, Formatter, CloseNotifier etc. If your type implements a method with the same meaning as a emthod with a well-known type, give it the same name and signature.
Control Structures
Related to C, but differ in important ways. There is no do
or while
loop, only a slightly generalized for
.
Switch
is more flexible. if
and switch
accept an optional init statement like for
.
break
and continue
take an optional label to identify what to break or continue.
Some new control structures are a type switch and a multiway communications multiplexer, select
.
If
if err := file.Chmod(0644); err != nil {
log.Print(err)
return err
}
Reusing variables with multiple declarations
f, err := os.Open(name)
if err != nil (
return err
}
d, err := f.Stat() // Note the reuse of err
if err != nil {
f.Close()
return err
}
codeUsing(f, d)
Braces are mandatory.
For
Three forms
// Like a C for
for init; conditionl post { }
// Like a C while
for condition { }
// Like a C for(;;)
for { }
Some examples
for key,value := range oldMap {
newMap[key] = value
}
// Even more efficient, drop the *value* from the range if we don't need it
for key := range m {
if key.expired() {
delete(m, key)
}
}
// If the second identifier is what is required, use the blank identifier to discard the first
for _, value := range array {
sum += value
}
Swich
Go switch
is more general than C’s.
- The expressions need not be constants or integers.
- The cases are evaluated top to bottom until a match is found
- If the switch has no expression, it switches on
true
. - There is no automatic fallthrough.
- Multiple cases can be presented in comma-seperated lists.
It is possible - and idiomatic - to write an if-else-if-else
chain as a switch,
func shouldEscape(c byte) bool {
switch c {
case ' ', '?', '&', '=', '#', '+', '%':
return true
}
return false
}
A more complicated example using a break
statement to terminate a switch early, and also using labels to break.
Loop:
for n := 0; n < len(src); n += size {
switch {
case src[n] < sizeOne:
if validateOnly {
break
}
size = 1
update(src[n])
case src[n] < sizeTwo: