Skip to content

Commit 3659645

Browse files
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 <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Rob Pike <[email protected]>
1 parent 8003e79 commit 3659645

File tree

2 files changed

+18
-3
lines changed

2 files changed

+18
-3
lines changed

src/flag/flag.go

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ import (
6868
"fmt"
6969
"io"
7070
"os"
71+
"reflect"
7172
"sort"
7273
"strconv"
7374
"time"
@@ -378,7 +379,21 @@ func Set(name, value string) error {
378379

379380
// isZeroValue guesses whether the string represents the zero
380381
// value for a flag. It is not accurate but in practice works OK.
381-
func isZeroValue(value string) bool {
382+
func isZeroValue(flag *Flag, value string) bool {
383+
// Build a zero value of the flag's Value type, and see if the
384+
// result of calling its String method equals the value passed in.
385+
// This works unless the Value type is itself an interface type.
386+
typ := reflect.TypeOf(flag.Value)
387+
var z reflect.Value
388+
if typ.Kind() == reflect.Ptr {
389+
z = reflect.New(typ.Elem())
390+
} else {
391+
z = reflect.Zero(typ)
392+
}
393+
if value == z.Interface().(Value).String() {
394+
return true
395+
}
396+
382397
switch value {
383398
case "false":
384399
return true
@@ -449,7 +464,7 @@ func (f *FlagSet) PrintDefaults() {
449464
s += "\n \t"
450465
}
451466
s += usage
452-
if !isZeroValue(flag.DefValue) {
467+
if !isZeroValue(flag, flag.DefValue) {
453468
if _, ok := flag.Value.(*stringValue); ok {
454469
// put quotes on the value
455470
s += fmt.Sprintf(" (default %q)", flag.DefValue)

src/flag/flag_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ const defaultOutput = ` -A for bootstrapping, allow 'any' type
393393
-Z int
394394
an int that defaults to zero
395395
-maxT timeout
396-
set timeout for dial (default 0s)
396+
set timeout for dial
397397
`
398398

399399
func TestPrintDefaults(t *testing.T) {

0 commit comments

Comments
 (0)