Golang code generation

Programs that produce source code are important elements in software engineering.
Since Go 1.4, the language ecosystem includes a command line tool that makes
it easier to run such tools.

It’s called go generate. It scans for special comments in Go
source code that identify general commands to run:

//go:generate <subcommand> <arguments>

Go generate is not part of go build. It does not do dependency analysis and
must be run explicitly before running go build. It is intended to be used by
the author of the Go package, not its consumers.

The go generate command is easy to use. Usually it is executed in the following way:

// it scans all
$ go generate ./...

After identifying all go:generate comments it will execute the specified commands.

In this article, we will explore a various tools that produce source code for us.

JSON Enums

Have you ever had an enum that you want to serialize in JSON as a string instead of integer?
Are you bored of developing a switch cases that handle that? It is time to automate this
task by using jsonenums.

Installing

Usage

Running go generate produces status_jsonenums.go file in the same package.
It contains the actual implementation for JSON serialization of Status enum.
Then we can serialize an enum variable in the following way:

Fast JSON

ffjson generates MarshalJSON and UnmarshalJSON functions for struct types.
These functions reduce the reliance unpon runtime reflection to do serialization.
According to the author notes, it is generally 2 to 3 times faster than
encoding/json package.

Installing

$ go get github.com/pquerna/ffjson

Usage

The generated code is baed upon existing struct types. Lets have education.go file.
ffjson will generate a new file education_ffjson.go that contains serialization
functions for all structs found in education.go. In order to do that we should
add the following go:generate comment in education.go:

Executing go generate ./... produces education_ffjson.go that contains all
json serialization code for Student and University structs. Then we can use
ffjson package to marshal these types and unmasrshal their JSON representation: