命令行参数StringVarP与BoolVarP区别"/>
cobra 命令行参数StringVarP与BoolVarP区别
使用cobra实现命令行参数解析的时候发现一个现象:bool类型参数和string类型参数解析时所需传入参数个数不一样, 假设有如下两行flag声明:
cmd.Flags().StringVarP(&strV, "strVar", "", "defaultS", "a string param")cmd.Flags().BoolVarP(&boolV, "boolVar", "", false, "a bool param")
在参数调用的时候就是
cmd --strV newS --boolV
可以注意到,第一个参数strV需要跟一个值“newS",但是第二个参数boolV就不需要。
经查看cobra源码,发现库在创建不同类型flag的时候做了区别处理:
// 1. bool类型参数设置了一个NoOptDefVal标志位为”true"
// github/spf13/pflag/bool.go
// BoolVarP is like BoolVar, but accepts a shorthand letter that can be used after a single dash.
func (f *FlagSet) BoolVarP(p *bool, name, shorthand string, value bool, usage string) {flag := f.VarPF(newBoolValue(value, p), name, shorthand, usage)flag.NoOptDefVal = "true"
}2. string类型没有对NoOptDefVal做设置,其值为""
// github/spf13/pflag/string.go
// StringVarP is like StringVar, but accepts a shorthand letter that can be used after a single dash.
func (f *FlagSet) StringVarP(p *string, name, shorthand string, value string, usage string) {f.VarP(newStringValue(value, p), name, shorthand, usage)
}
然后在解析传入参数的时候根据flag的NoOptDefVal值做了分支处理:
github/spf13/pflag/flag.gofunc (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []string, err error) {a = argsname := s[2:]if len(name) == 0 || name[0] == '-' || name[0] == '=' {err = f.failf("bad flag syntax: %s", s)return}split := strings.SplitN(name, "=", 2)name = split[0]flag, exists := f.formal[f.normalizeFlagName(name)]......var value stringif len(split) == 2 {// '--flag=arg'value = split[1]} else if flag.NoOptDefVal != "" { // 若该值不为空,直接取值,不需要解析后面的参数// '--flag' (arg was optional)value = flag.NoOptDefVal} else if len(a) > 0 { // 否则解析后一个参数作为本参数的值// '--flag arg'value = a[0]a = a[1:]} else {// '--flag' (arg was required)err = f.failf("flag needs an argument: %s", s)return}err = fn(flag, value)if err != nil {f.failf(err.Error())}return
}
这就能解释为什么bool类型参数不需要跟一个值:它本身就代表true,不显示添加参数则表示false;而string类型参数则需要跟一个值。
更多推荐
cobra 命令行参数StringVarP与BoolVarP区别
发布评论