Читать книгу Practical Go - Amit Saha - Страница 38
Listing 1.5: Greeter using flag
Оглавление// chap1/flag-parse/main.go package main import ( "bufio" "errors" "flag" "fmt" "io" "os" ) type config struct { numTimes int } // TODO Insert definition of getName() as Listing 1.1 // TODO Insert definition of greetUser() as Listing 1.1 // TODO Insert definition of runCmd() as Listing 1.1 // TODO Insert definition of validateArgs as Listing 1.1 func parseArgs(w io.Writer, args []string) (config, error) { c := config{} fs := flag.NewFlagSet("greeter", flag.ContinueOnError) fs.SetOutput(w) fs.IntVar(&c.numTimes, "n", 0, "Number of times to greet") err := fs.Parse(args) if err != nil { return c, err } if fs.NArg() != 0 { return c, errors.New("Positional arguments specified") } return c, nil } func main() { c, err := parseArgs(os.Stderr, os.Args[1:]) if err != nil { fmt.Fprintln(os.Stdout, err) os.Exit(1) } err = validateArgs(c) if err != nil { fmt.Fprintln(os.Stdout, err) os.Exit(1) } err = runCmd(os.Stdin, os.Stdout, c) if err != nil { fmt.Fprintln(os.Stdout, err) os.Exit(1) } }
The config
struct type is modified so that it doesn't have the printUsage
field since the parseArgs()
function now automatically handles the -h
or -help
argument. Create a new directory, chap1/flag-parse/
, and initialize a module inside it:
$ mkdir -p chap1/flag-parse $ cd chap1/flag-parse $ go mod init github.com/username/flag-parse
Next, save Listing 1.5 to a file called main.go
and build it:
$ go build -o application
Run the command without specifying any arguments. You will see the following error message:
$ ./application Must specify a number greater than 0
Now run the command specifying the -h
option:
$ ./application -h Usage of greeter: -n int Number of times to greet flag: help requested
The flag parsing logic recognized the -h
option and displayed a default usage message consisting of the name that was specified when calling the NewFlagSet()
function and the options along with their name, type, and description. The last line of the above output is seen here because when we haven't explicitly defined an -h
option, the Parse()
function returns an error, which is displayed as part of the error handling logic in main()
. In the next section, you will see how we can improve this behavior.
Next, let's invoke the program specifying a non-integral value for the -n
option:
$ ./application -n abc invalid value "abc" for flag -n: parse error Usage of greeter: -n int Number of times to greet invalid value "abc" for flag -n: parse error
Note how we automatically get the type validation error since we tried specifying a non-integral value. In addition, note here again that we get the error twice. We will fix this later in the chapter.
Finally, let's run the program with a valid value for the -n
option:
$ ./application -n 4 Your name please? Press the Enter key when done. John Doe Nice to meet you John Doe Nice to meet you John Doe Nice to meet you John Doe Nice to meet you John Doe