liveBook · Manning

Go generate

As explained in Go in Practice, Second Edition

go generate is a Go command that executes source-code generation directives embedded in Go files.

When several Go types need the same repetitive implementation, a generator can write the declarations instead of duplicating them by hand or using runtime reflection. `go generate` runs the commands named in source-file directives; the resulting Go code is compiled afterward. This is useful when generics are not applicable and type-safe generated code is preferable to reflection’s runtime overhead. section 13.3 section 13.0

//go:generate COMMAND [ARGUMENT...]

A `//go:generate` comment names a command and its arguments. Running `go generate` executes the directive; the command must do the actual code generation. section 13.3

For a typed queue, the generator uses `text/template` to substitute a type name into queue declarations. It reads type names from command-line arguments, obtains the package name from `GOPACKAGE`, and writes a separate `_queue.go` file for each type. The generated methods then operate on a slice of that type. section 13.3

Listing 13.20 The main queue generator
func main() {
     tt := template.Must(template.New("queue").Parse(tpl))   #1
     for i := 1; i < len(os.Args); i++ {                 #2
            dest := strings.ToLower(os.Args[i]) + 
            "_queue.go"                                    
            file, err := os.Create(dest)
            if err != nil {
                   fmt.Printf("Could not create %s: %s (skip)\n", 
                   dest, err)
                   continue
            }
            vals := map[string]string{
                   "MyType":  os.Args[i],                   #3
                   "Package": os.Getenv("GOPACKAGE"),   #4
            }
            tt.Execute(file, vals)   #5

            file.Close()            
     }

}

The generator’s main function shows the work behind the directive: parse the template, iterate over type-name arguments, create output files, and execute the template with the type and package values. section 13.3

Generate and use a typed queue

Place `//go:generate ./queue MyInt` in a Go file that declares `type MyInt int`. With the `queue` executable available at that path, run `go generate`. The generator creates `myint_queue.go`; running `go run myint.go myint_queue.go` then uses `NewMyIntQueue`, `Insert`, and `Remove` to print `First value: 1`. Generation is an explicit step before running the program. section 13.3

How Go in Practice, Second Edition covers it

How deep it goes
Works through directive syntax, a template-based generator, generated queue usage, and shell commands.
Examples
Uses an echo directive and a typed queue generator that writes a `_queue.go` file.
What it assumes
Assumes basic Go files, types, and command-line use while demonstrating the generator and its template.
What you can do after
Build it from scratch as a template-based queue generator and run `go generate` before compiling its output.
How it connects
Connects code generation with generics, runtime reflection, Go templates, and type-safe code.

Also explained in

Compare how 2 books explain go generate →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Go in Practice, Second Edition. The section links point to the parts of the book it draws on.