我正在使用go的本机"flag"
包。
其中内置了使用flag.VisitAll
访问所有当前定义的标志的功能。
我正在尝试构建一个片段,尝试从环境变量中获取该标志的值(如果存在)并且万一未设置该标志的情况,并且我无法找到一种方法来确定是否特定标记是否已设置。
有什么方法可以实现而无需实现新的参数类型?
答案 0 :(得分:2)
使用flag.VisitAll
听起来有点令人费解。我建议使用默认的默认环境变量并将其用作标志的默认值-这意味着如果未设置该标志,则环境变量将作为后备:
package main
import (
"flag"
"fmt"
"os"
)
func GetEnvDefault(key, def string) string {
v := os.Getenv(key)
if v == "" {
return def
}
return v
}
func main() {
// Uncomment to test behaviour
// os.Setenv("SERVER_NAME", "donaldduck")
var serverName string
flag.StringVar(&serverName, "n", GetEnvDefault("SERVER_NAME", "mickeymouse"), "The human name for the server")
flag.Parse()
fmt.Println(serverName)
}
答案 1 :(得分:0)
没有任何功能可以遍历未设置的命令行标志。但是,可以通过利用VisitAll
和Visit
返回的标志之间的差异来复制此功能。前者遍历所有标志,而后者遍历设置的标志:
func UnsetFlags(fs *flag.FlagSet) []*flag.Flag {
var unset []*flag.Flag
fs.VisitAll(func(f *flag.Flag) {
unset = append(unset, f)
})
fs.Visit(func(f *flag.Flag) {
for i, h := range unset {
if f == h {
unset = append(unset[:i], unset[i+1:]...)
}
}
})
return unset
}
您可以在flag.Parse
调用之后使用该函数来将所有未设置的标志设置为其环境值:
for _, f := range UnsetFlags(flag.CommandLine) {
v := os.Getenv(f.Name)
f.Value.Set(v)
}