How to use the command 'go generate' (with examples)
go generate
is a utility provided by the Go programming language to automate the generation of Go source files by executing commands specified in the special comments within the Go source files. This tool is particularly useful in scenarios where repetitive code or boilerplate needs to be generated from specific instructions, thereby saving both time and reducing human error.
Use case 1: Generate Interface Implementations
Code:
//go:generate stringer -type=Pill
type Pill int
const (
Placebo Pill = iota
Asprin
Ibuprofen
Paracetamol
)
Motivation:
In Go, writing out all string representations for constants manually can be quite tedious and error-prone, especially when new constants are added or values change. Using go generate
, developers can automate the creation of methods, such as Stringers, which implement the String() string
method for an enumeration of constants. This ensures consistency and minimizes the potential for human error in maintaining the mappings.
Explanation:
//go:generate
is a directive used to indicate that the following command should be run whengo generate
is executed.stringer -type=Pill
is the command that will be executed.stringer
is a code generation utility for creatingString()
methods for Go types.-type=Pill
specifies the enum type that we want to have aString()
method generated for.
Example Output:
Running go generate
will generate a new file, pill_string.go
, with content similar to:
// Code generated by "stringer -type=Pill"; DO NOT EDIT.
package main
import "strconv"
func (p Pill) String() string {
switch p {
case Placebo:
return "Placebo"
case Asprin:
return "Asprin"
case Ibuprofen:
return "Ibuprofen"
case Paracetamol:
return "Paracetamol"
}
return "Pill(" + strconv.Itoa(int(p)) + ")"
}
Use case 2: Embed Static Files
Code:
//go:generate go-bindata -o assets.go ./templates/...
Motivation:
Embedding static files such as HTML templates, images, or configuration files directly into the Go binary can be useful when deploying applications across different environments where file paths change. By embedding these files, deployment and distribution become easier and more portable, reducing dependencies on file structure and making version management simpler.
Explanation:
//go:generate
acts as a directive to execute the specified command whengo generate
is run.go-bindata
is a third-party package used to convert assets into Go source files.-o assets.go
specifies that the output file should be namedassets.go
, where the embedded asset data will be stored../templates/...
tellsgo-bindata
to embed all files within thetemplates
directory.
Example Output:
Executing go generate
will produce a file assets.go
containing Go source code with embedded asset data, allowing you to access the files within your Go app like so:
data, err := Asset("templates/example.html")
if err != nil {
// Handle error
}
fmt.Println(string(data))
Conclusion:
The go generate
command is a powerful tool in Go’s ecosystem, enabling developers to automate and integrate code generation directly into the build process. Whether it’s creating interface implementations or embedding static resources, go generate
helps maintain consistent, error-free code bases with reduced manual overhead. The approach taken through go generate
can significantly enhance productivity and ensure reliability in code maintenance and deployment tasks.