liveBook · Manning

Custom flag parser

As explained in Go by Example

A custom flag parser is program logic that interprets command-line flag names and values and assigns the parsed values to configuration fields.

A custom flag parser converts raw command-line arguments into typed configuration values. It accepts a configuration pointer and argument slice, then updates the original configuration while parsing. section 4.2.3 section 4.2

Build the parser around a map of flag names to type-specific setter functions:

  • Bind each name to a parser closure, such as "url": stringVar(&c.url) and "n": intVar(&c.n). section 4.2.3
  • Wrap conversion failures with fmt.Errorf and %w so callers retain the original error, including strconv.ErrSyntax from Atoi. section 4.2.3

Configuration-driven parsing

Given a config containing url, n, c, and rps fields, parseArgs binds "url" to stringVar(&c.url) and the numeric flags to intVar closures. Each closure retains its field pointer and assigns the parsed value, leaving the configuration ready for the command-line tool. section 4.2.3

Listing 4.3 Flag parser (hit/cmd/hit/config.go)
package main

import (
    "fmt"
    "strings"
    . . .
)

type config struct {
    url string
    n   int
    c   int
    rps int
}

func parseArgs(c *config, args []string) error {
    flagSet := map[string]parseFunc{  #1
        "url": stringVar(&c.url),  #2
        "n":   intVar(&c.n),  #3
        "c":   intVar(&c.c),   #3
        "rps": intVar(&c.rps),   #3
    }

    for _, arg := range args {
        name, val, _ := strings.Cut(arg, "=")  #4
        name = strings.TrimPrefix(name, "-")  #5

        setVar, ok := flagSet[name]  #6
        if !ok {
           return fmt.Errorf(
                "flag provided but not defined: -%s",
                name,
            )
        }
        if err := setVar(val); err != nil { #7
            return fmt.Errorf(  #8
                "invalid value %q for flag -%s: %w",  #8
                val, name, err,   #8
            )   #8
        }
    }

    return nil
}

Inspect the complete parseArgs implementation, including configuration fields, flag bindings, argument handling, lookup, and error paths. section 4.2.3

How Go by Example covers it

How deep it goes
Explains parsing steps, closures, pointer sharing, lookup errors, wrapped conversion errors, and basic escape-analysis observations.
Examples
Uses url, n, c, and rps flags mapped to string and integer configuration fields.
What it assumes
Assumes basic Go functions, maps, pointers, closures, errors, and command-line arguments while teaching manual flag parsing incrementally.
What you can do after
Build it from scratch with os arguments, typed setter closures, unknown-flag checks, and wrapped conversion errors.
How it connects
Connects command-line arguments with closures, higher-order functions, type-safe variables, error wrapping, and the flag package.

Related concepts

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