Rob Pike | 07e887f | 2012-03-22 11:15:43 +1100 | [diff] [blame] | 1 | // Copyright 2012 The Go Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style |
| 3 | // license that can be found in the LICENSE file. |
| 4 | |
| 5 | // These examples demonstrate more intricate uses of the flag package. |
| 6 | package flag_test |
| 7 | |
| 8 | import ( |
| 9 | "errors" |
| 10 | "flag" |
| 11 | "fmt" |
| 12 | "strings" |
| 13 | "time" |
| 14 | ) |
| 15 | |
| 16 | // Example 1: A single string flag called "species" with default value "gopher". |
| 17 | var species = flag.String("species", "gopher", "the species we are studying") |
| 18 | |
| 19 | // Example 2: Two flags sharing a variable, so we can have a shorthand. |
| 20 | // The order of initialization is undefined, so make sure both use the |
| 21 | // same default value. They must be set up with an init function. |
| 22 | var gopherType string |
| 23 | |
| 24 | func init() { |
| 25 | const ( |
| 26 | defaultGopher = "pocket" |
| 27 | usage = "the variety of gopher" |
| 28 | ) |
| 29 | flag.StringVar(&gopherType, "gopher_type", defaultGopher, usage) |
| 30 | flag.StringVar(&gopherType, "g", defaultGopher, usage+" (shorthand)") |
| 31 | } |
| 32 | |
| 33 | // Example 3: A user-defined flag type, a slice of durations. |
| 34 | type interval []time.Duration |
| 35 | |
| 36 | // String is the method to format the flag's value, part of the flag.Value interface. |
| 37 | // The String method's output will be used in diagnostics. |
| 38 | func (i *interval) String() string { |
| 39 | return fmt.Sprint(*i) |
| 40 | } |
| 41 | |
| 42 | // Set is the method to set the flag value, part of the flag.Value interface. |
| 43 | // Set's argument is a string to be parsed to set the flag. |
| 44 | // It's a comma-separated list, so we split it. |
| 45 | func (i *interval) Set(value string) error { |
| 46 | // If we wanted to allow the flag to be set multiple times, |
| 47 | // accumulating values, we would delete this if statement. |
| 48 | // That would permit usages such as |
| 49 | // -deltaT 10s -deltaT 15s |
| 50 | // and other combinations. |
| 51 | if len(*i) > 0 { |
| 52 | return errors.New("interval flag already set") |
| 53 | } |
| 54 | for _, dt := range strings.Split(value, ",") { |
| 55 | duration, err := time.ParseDuration(dt) |
| 56 | if err != nil { |
| 57 | return err |
| 58 | } |
| 59 | *i = append(*i, duration) |
| 60 | } |
| 61 | return nil |
| 62 | } |
| 63 | |
| 64 | // Define a flag to accumulate durations. Because it has a special type, |
| 65 | // we need to use the Var function and therefore create the flag during |
| 66 | // init. |
| 67 | |
| 68 | var intervalFlag interval |
| 69 | |
| 70 | func init() { |
| 71 | // Tie the command-line flag to the intervalFlag variable and |
| 72 | // set a usage message. |
| 73 | flag.Var(&intervalFlag, "deltaT", "comma-separated list of intervals to use between events") |
| 74 | } |
| 75 | |
| 76 | func Example() { |
| 77 | // All the interesting pieces are with the variables declared above, but |
| 78 | // to enable the flag package to see the flags defined there, one must |
| 79 | // execute, typically at the start of main (not init!): |
| 80 | // flag.Parse() |
| 81 | // We don't run it here because this is not a main function and |
| 82 | // the testing suite has already parsed the flags. |
| 83 | } |