Golang Documenting Package Examples
Go has been gaining a lot of popularity recently. With a lot of the success stories centered on the performance gains switching from other languages. For me a lot of the smaller features, that shows an attention to detail, which makes it enjoyable to code in.
These details are also what will help the Golang community grow as well. One of these details is the built in documentation into the language.
There is a built in go doc command with the language where you can view your
package documentation locally by running an http server to serve your docs.
GoDoc is the main hosting for open source packages that
will build docs for your package by doing a go get and generating docs.
Locally you can run go doc from your package to display the docs in your
terminal.
$ cd $GOPATH/src/github.com/mtchavez/go-statsite/statsite
$ go doc
PACKAGE DOCUMENTATION
package statsite
    import "github.com/mtchavez/go-statsite/statsite"
VARIABLES
var MTypes []string = []string{
    "kv",
    "g",
    "ms",
    "c",
    "s",
}
TYPES
type Client struct {
    Conn net.Conn
    // contains filtered or unexported fields
}
func NewClient(addr string) (client *Client, err error)
func (c *Client) Emit(m Messenger) (bool, error)
func (c *Client) Emitter(msg string) (ok bool, err error)
Or you can view all the packages in your $GOSRC directory as well as the
standard library code in your browser by running godoc -http=:6060. Then
visit localhost:6060 in your browser. This looks the same as golang.org you
may notice. Click on Packages and find the package you are looking for. This
all comes built into the language itself.
If you have spent any time using go, browsed the standard library docs, used
an open source go project you may have notice a Examples in docs. These
examples are one of the details I mentioned that add to the language and help
grow a community. Here is an
example of the built in time package examples. The novel thing about this is
it is just the built in examples from the Go source that get generated by go doc from the language itself. There is no extra documentation package or
custom manages site.
So you have an open source project, or some internal go project, that you want
to make life easier for others to pick up and understand. Lets write an
example for them to understand how to use your package. Lets say you have a
fibonacci number generator package. And you want to show someone how to use it
with an example. Lets add a $GOPATH/src/fib directory with a fib.go main
package with the following:
package fib
import (
  "fmt"
  "os"
  "strconv"
)
func fib(n int) int {
  if n < 2 {
    return n
  }
  return fib(n-1) + fib(n-2)
}
Since we’ll be expecting others to use our package we’ll want to test it works
as well as document how to use it. With examples we can do both in one shot.
In our same $GOPATH/src/fib directory create a fib_test.go file. Lets add
our example test.
package fib
import (
  "fmt"
)
func Example() {
  var output int
  output = fib(10)
  fmt.Printf("Fibonacci of %v is %v\n", 10, output)
  output = fib(20)
  fmt.Printf("Fibonacci of %v is %v\n", 20, output)
  // Output:
  // Fibonnacci of 10 is 55
  // Fibonnacci of 20 is 6765
}
Now from your fib/ directory run go test and you should see some similar
output:
$ go test
PASS
ok    fib 0.023s
This allowed us to both test our fibonacci package and show someone else an example how to use it. If the output changed or we broke our package our tests should fail as well.
$ go test
--- FAIL: Example (80.68us)
got:
Fibonacci of 10 is 55
Fibonacci of 20 is 6765
want:
Fibonacci of 10 is 55
Fibonacci of 20 is 55
FAIL
exit status 1
FAIL  fib 0.018s
Simple enough. What if you have a struct where you are calling a function off
of and want to show how one would use the function. The principal is the same
except we change our Example() function name in our test. If we change our
fib.go to this:
package fib
import (
  "fmt"
  "os"
  "strconv"
)
type FibStruct struct {
  num    int
  result int
}
func fib(n int) int {
  if n < 2 {
    return n
  }
  return fib(n-1) + fib(n-2)
}
func (f *FibStruct) Calculate(num int) {
  f.num = num
  f.result = fib(num)
}
Then we can add an example on how to use our new Calculate() method in
fib_test.go.
func ExampleFibStruct_Calculate() {
  f := FibStruct{}
  f.Calculate(10)
  fmt.Printf("Fibonacci of %v is %v\n", 10, f.result)
  f.Calculate(20)
  fmt.Printf("Fibonacci of %v is %v\n", 20, f.result)
  // Output:
  // Fibonacci of 10 is 55
  // Fibonacci of 20 is 6765
}
Running the tests again with go test should show everything passing. Last
part to this is viewing your examples via go doc or on
GoDoc. You can view this example at fib-go-
example.