diff options
author | Ian Lance Taylor <iant@golang.org> | 2016-05-31 11:23:50 -0700 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2016-05-31 23:45:47 +0000 |
commit | 3659645cb1f32d7b1eeefdb65f1339fe54f0f6eb (patch) | |
tree | 42100becf762fe9f3905bfcc6d21977f0526be1a | |
parent | 8003e791549f011edcc2a9d1eacbd5674826d38c (diff) | |
download | go-3659645cb1f32d7b1eeefdb65f1339fe54f0f6eb.tar.gz go-3659645cb1f32d7b1eeefdb65f1339fe54f0f6eb.zip |
flag: recognize "0s" as the zero value for a flag.Duration
Implemented by using a reflect-based approach to recognize the zero
value of any non-interface type that implements flag.Value. Interface
types will fall back to the old code.
Fixes #15904.
Change-Id: I594c3bfb30e9ab1aca3e008ef7f70be20aa41a0b
Reviewed-on: https://go-review.googlesource.com/23581
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
-rw-r--r-- | src/flag/flag.go | 19 | ||||
-rw-r--r-- | src/flag/flag_test.go | 2 |
2 files changed, 18 insertions, 3 deletions
diff --git a/src/flag/flag.go b/src/flag/flag.go index 6acbbcd321..fa0f05e968 100644 --- a/src/flag/flag.go +++ b/src/flag/flag.go @@ -68,6 +68,7 @@ import ( "fmt" "io" "os" + "reflect" "sort" "strconv" "time" @@ -378,7 +379,21 @@ func Set(name, value string) error { // isZeroValue guesses whether the string represents the zero // value for a flag. It is not accurate but in practice works OK. -func isZeroValue(value string) bool { +func isZeroValue(flag *Flag, value string) bool { + // Build a zero value of the flag's Value type, and see if the + // result of calling its String method equals the value passed in. + // This works unless the Value type is itself an interface type. + typ := reflect.TypeOf(flag.Value) + var z reflect.Value + if typ.Kind() == reflect.Ptr { + z = reflect.New(typ.Elem()) + } else { + z = reflect.Zero(typ) + } + if value == z.Interface().(Value).String() { + return true + } + switch value { case "false": return true @@ -449,7 +464,7 @@ func (f *FlagSet) PrintDefaults() { s += "\n \t" } s += usage - if !isZeroValue(flag.DefValue) { + if !isZeroValue(flag, flag.DefValue) { if _, ok := flag.Value.(*stringValue); ok { // put quotes on the value s += fmt.Sprintf(" (default %q)", flag.DefValue) diff --git a/src/flag/flag_test.go b/src/flag/flag_test.go index 1a8bdc106a..e2319ec94c 100644 --- a/src/flag/flag_test.go +++ b/src/flag/flag_test.go @@ -393,7 +393,7 @@ const defaultOutput = ` -A for bootstrapping, allow 'any' type -Z int an int that defaults to zero -maxT timeout - set timeout for dial (default 0s) + set timeout for dial ` func TestPrintDefaults(t *testing.T) { |