godoc: Tips & Tricks

Elliot Chance
5 min readJun 11, 2016

--

Go has a great emphasis on simple, no-nonsense documentation right out of the box. Rather than using an existing format (like Markdown) where formatting is often explicitly stated godocuses many implicit rules to extract quality documentation from really plain text so that you can spend less time formatting your documentation and more time writing it.

godoccan produce docs in several formats, such as text (similar to a man page) but the most common one you will come across is the HTML version.

In this article I will be focusing on how the formatting is produced rather than how to use the godoccommand-line tool itself. It has a whole bunch of other options that are well documented.

Package Overview & License

// Copyright Some Company Corp.
// All Rights Reserved
// Here is where we explain the package.
// Some other stuff.
package doc

Package level documentation must be in a continuous comment immediately preceding the packagestatement. If there is a blank line between the comment and the packagestatement it will be discarded. This is how you add comments that should or should not be included in the general package documentation.

The first sentence is important because it is automatically extracted as the brief overview for the package when listing all the packages, like:

Since a package can be made up of more than one file you can spread the package documentation across files and godocwill merge all of these into the same Overview block. The order, as far as I’m aware, is not guaranteed to be predicable. But it does offer a nice way to document parts of the package in the individual files that make sense.

Alternatively, you can add a file to your package which contains no code but the complete package documentation and a single packagestatement if that makes sense too.

Paragraphs

To make wrapping long continuing lines easier godocwill assume that all subsequent lines are part of the same paragraph. However, you can explicitly separate paragraphs with a blank line (you still need to put the // so that the comment is one continuous block). If you’re familiar with Markdown then this works the same way.

// Here is where we explain the package.
//
// Some other stuff.
package doc

Constants

Many packages contain exported constants. Those that are exported are very important to document. This can be one of two ways, the first is to document all the constvalues independently:

// This is the host
const Host = "example.com"
// The port number for the host.
const Port = 1234

If you have const values that are related it might be better to include them in a single const declaration:

// This appears under the const.
const (
// This causes Foo to happen.
OptionFoo = 1
// This causes Bar to happen.
OptionBar = 2
// Documented, but not visible.
optionSecret = 3
)

Methods

// Math stuff.// Absolute value.
func Abs(x float64) float64 {
}
// Sine value.
func Sin(x float64) float64 {
}
// Internal stuff.// Docs are important even for internal stuff.
func secretMethod() {
}

Make sure the comment is immediately preceding the method (like the the package) otherwise godoc will not include it in the output:

Only exported methods are included in the documentation:

Headings & Sections

Go is sensitive to things that look like (or don’t look like) sentences. godoc recognises a line that starts with a capital letter and does not end in a full stop as a heading.

// Here is where we explain the package.
//
// See Also
//
// Some other stuff.
package doc

Code Blocks

Code blocks let you add inline-code examples. The are identified as line that starts with at least one extra space (after the single space for //)

// This is how to create a Hello World:
// fmt.Printf("Hello, World")
// Or:
// fmt.Printf("Hello, " + name)

Code blocks do not employ code-colouring, but this means they can be used for documenting any other non-go code, such as bash.

Links

Links are automatically recognised.

Examples

You can include an example at the package-level by creating a function called Example in your package or the test package (with a _test suffix):

// My awesome package.
package doc
package doc_test// This is a package-level example:
func Example() {
fmt.Printf("Hi")
}
// This is a package-level example:
func Example() {
fmt.Printf("Hi")
}

You can attach examples to types by adding the type name to the Examplemethod:

package doc// Real is just another name for float64.
type Real float64
package doc_test// Use Real like a general floating type:
func ExampleReal() {
var x Real = 1.23
}

This same strategy is used for methods. In all cases if you need to provide more than one example you can add an underscore suffix after the method name to name each example. The name of the example will also be shown in the documentation.

Also, a special comment can be used to designate what the output of the example will be.

package doc// Absolute value.
func Abs(x Real) Real {
}
package doc_testfunc ExampleAbs_positive() {
Abs(1.23)
// Output: 1.23
}
func ExampleAbs_negative() {
Abs(-1.23)
// Output: 1.23
}

Originally published at http://elliot.land on June 11, 2016.

--

--

Elliot Chance
Elliot Chance

Written by Elliot Chance

I’m a data nerd and TDD enthusiast originally from Sydney. Currently working for Uber in New York. My thoughts here are my own. 🤓 elliotchance@gmail.com

Responses (2)