Pet*_*lák 36 command-line-interface go command-line-arguments
有没有办法设置某些标志是强制性的,还是我必须自己检查它们的存在?
正如已经提到的,该flag包不直接提供这个功能,通常你可以(也应该)能够提供一个合理的默认。如果您只需要少量的显式参数(例如,输入和输出文件名),则可以使用位置参数(例如,flag.Parse()先检查flag.NArg()==2后再选择input, output := flag.Arg(0), flag.Arg(1))。
但是,如果您遇到这种情况并不明智;说出您要以任何顺序接受的一些整数标志,其中任何整数值都是合理的,但没有默认值。然后,您可以使用该flag.Visit功能来检查您关心的标志是否已显式设置。我认为这是判断标志是否明确设置为其默认值的唯一方法(不flag.Value使用Set保留状态的实现来计算自定义类型)。
例如,也许类似:
required := []string{"b", "s"}
flag.Parse()
seen := make(map[string]bool)
flag.Visit(func(f *flag.Flag) { seen[f.Name] = true })
for _, req := range required {
if !seen[req] {
// or possibly use `log.Fatalf` instead of:
fmt.Fprintf(os.Stderr, "missing required -%s argument/flag\n", req)
os.Exit(2) // the same exit code flag.Parse uses
}
}
Run Code Online (Sandbox Code Playgroud)
如果未显式设置“ -b”或“ -s”标志,则将产生错误。
我喜欢github.com/jessevdk/go-flags在CLI中使用的包.它是提供required属性,设置标志为必需.像那样:
var opts struct {
...
// Example of a required flag
Name string `short:"n" long:"name" description:"A name" required:"true"`
...
}
Run Code Online (Sandbox Code Playgroud)
go-flags 允许您声明所需的标志和必需的位置参数:
var opts struct {
Flag string `short:"f" required:"true" name:"a flag"`
Args struct {
First string `positional-arg-name:"first arg"`
Sencond string `positional-arg-name:"second arg"`
} `positional-args:"true" required:"2"`
}
args, err := flags.Parse(&opts)
Run Code Online (Sandbox Code Playgroud)
如果您有标志路径,只需检查 *path 是否包含某些值
var path = flag.String("f", "", "/path/to/access.log")
flag.Parse()
if *path == "" {
usage()
os.Exit(1)
}
Run Code Online (Sandbox Code Playgroud)
小智 6
我同意这个解决方案,但就我而言,默认值通常是环境值。例如,
dsn := flag.String("dsn", os.Getenv("MYSQL_DSN"), "data source name")
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我想检查这些值是否是从调用(通常是本地开发)或环境变量(产品环境)中设置的。
因此,经过一些小的修改,它适用于我的情况。
使用flag.VisitAll检查所有标志的值。
required := []string{"b", "s"}
flag.Parse()
seen := make(map[string]bool)
flag.VisitAll(func(f *flag.Flag) {
if f.Value.String() != "" {
seen[f.Name] = true
}
})
for _, req := range required {
if !seen[req] {
// or possibly use `log.Fatalf` instead of:
fmt.Fprintf(os.Stderr, "missing required -%s argument/flag\n", req)
os.Exit(2) // the same exit code flag.Parse uses
}
}
Run Code Online (Sandbox Code Playgroud)