From 3659645cb1f32d7b1eeefdb65f1339fe54f0f6eb Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 31 May 2016 11:23:50 -0700 Subject: [PATCH] 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 TryBot-Result: Gobot Gobot Reviewed-by: Rob Pike --- src/flag/flag.go | 19 +++++++++++++++++-- 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) { -- 2.50.0