如何使标志忽略未知输入并将其存储以供进一步处理? 我看过一些关于 const IgnoreUnknown 的内容,但我不确定如何使用它,因为当我尝试将其如下所示时,没有任何改变:
const (
IgnoreUnknown = true
)
文档很差,所以为了以后的参考,应该这样做:
parser := flags.NewParser(&opt, flags.IgnoreUnknown)
args, _ := parser.Parse()
您可以在手动将未知标志传递给
FlagSet.Parse()
之前删除它们。
func StripUnknownFlags(flagSet *flag.FlagSet, args []string) []string {
formalFlagNames := getFormalFlagNames(flagSet)
res := make([]string, 0, len(args))
for i := 0; i < len(args); i++ {
arg := args[i]
isFlag, isTerminator, flagName, hasInlineValue := parseArg(arg)
if isTerminator {
res = append(res, args[i:]...)
break
}
if !isFlag {
res = append(res, arg)
continue
}
isBoolFlag, exists := formalFlagNames[flagName]
if exists {
res = append(res, arg)
continue
}
if !hasInlineValue && !isBoolFlag {
i++ // strip next arg (current flag value)
}
}
return res
}
func parseArg(arg string) (isFlag bool, isTerminator bool, flagName string, hasInlineValue bool) {
if len(arg) < 2 || arg[0] != '-' {
return false, false, "", false
}
numMinuses := 1
if arg[1] == '-' {
numMinuses++
if len(arg) == 2 { // "--" terminates the flags
return false, true, "", false
}
}
flagName = arg[numMinuses:]
if equalsSignIndex := strings.Index(flagName, "="); equalsSignIndex == 0 {
// std FlagSet.Parse() will return "bad flag syntax" error
return false, false, "", false
} else if equalsSignIndex > 0 {
flagName = flagName[:equalsSignIndex]
hasInlineValue = true
}
return true, false, flagName, hasInlineValue
}
// getFormalFlagNames returns a map where key is a flag name and value indicates it's a bool flag
func getFormalFlagNames(flagSet *flag.FlagSet) map[string]bool {
flags := make(map[string]bool)
flagSet.VisitAll(func(f *flag.Flag) {
isBoolFlag := false
if boolFlag, ok := f.Value.(boolFlag); ok {
isBoolFlag = boolFlag.IsBoolFlag()
}
flags[f.Name] = isBoolFlag
})
return flags
}
代码来自 github.com/cardinalby/go-struct-flags 具有此功能的包。