Skip to content
This repository has been archived by the owner on May 10, 2019. It is now read-only.

Latest commit

 

History

History
77 lines (54 loc) · 3.1 KB

go.md

File metadata and controls

77 lines (54 loc) · 3.1 KB

Go style guide

The purpose of this style guide is to provide some conventions for working on Go code within GDS. There are already good resources on writing Go code, which are worth reading first:

Code formatting

Use gofmt. This means all Go code reads in the same way which is important when looking at unfamiliar code.

You may also want to use golint which assesses code style.

Code checking

govet, which checks correctness, should be used as part of your build process.

If you are writing concurrent code, use the race detector to detect race conditions.

External dependencies

There is no centrally-mandated dependency manager for Go, which means a few techniques have sprung up. These include:

  • tools like godep and gom, which ensure local copies of a dependency are checked out to a specific version
  • vendoring (ie copying source code in some manner to a location you control)
  • gopkg.in, which provides a method of using versioned import paths

We are currently evaluating godep and gom as tools for managing dependencies. While godep is probably more widely used, gom offers some conveniences for modifying $GOPATH, which is useful for isolating jenkins builds. If you are using a different CI process, godep may be sufficient for your needs.

Web frameworks

While it's difficult to provide any guidance that will be generally applicable, there are couple of useful things to consider when structuring your Go program.

The first is that Go's standard library is modern and powerful. If you just need simple HTTP routing and handling, the net/http package will probably meet your needs.

The second is that if net/http falls short, it's worth choosing something that integrates well with it. The gorilla toolkit provides some excellent additions to net/http.

Channels

Signalling

Channels that are being used purely for signalling should use an empty struct rather than boolean or int types.

Using an empty struct declares that we're not interested in the value sent or received; only in its closed property.

See http://talks.golang.org/2012/10things.slide#11

func worker(quit <-chan struct{}, result chan<- int) {
  for {
    select {
    case result <- rand.Intn(10000000):
    case <-quit:
      return
    }
  }
}

func main() {
  quit, result := make(chan struct{}), make(chan int)
  for i := 0; i < 100; i++ {
    go worker(quit, result)
  }
  // Wait for a worker to return a good result
  for {
    if <-result > 9999998 {
      break
    }
  }
  close(quit) // terminate all the workers
  fmt.Println("All done!")
}