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 called Owner (upper case, exported). The setter could be called SetOwner.
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:
comments powered by Disqus