检查 Go 中是否提供了标志

用flag包,有没有什么好办法区分是否传入了字符串flag?


比如没有传递flag的时候,我想设置一个动态的默认值。但是,如果提供了标志但值为"".


目前我正在做以下事情:


flagHost = flag.String(flagHostFlagKey, "", "...")

...

setHostname := false

for _, arg := range os.Args {

    if arg == "-"+flagHostFlagKey {

        setHostname = true

    }

}


if !setHostname {

     ...

这似乎工作正常,但有点丑陋。在使用标准标志包的同时还有更好的方法吗?


慕运维8079593
浏览 133回答 3
3回答

白猪掌柜的

使用flag.Visit()函数:func isFlagPassed(name string) bool {    found := false    flag.Visit(func(f *flag.Flag) {        if f.Name == name {            found = true        }    })    return found}

慕虎7371278

内置标志类型不支持区分默认值和对默认值的显式分配。但是,该flag包非常灵活,并允许您使用flag.Value接口滚动自己的类型。这是一个完整的示例,其中包含一个字符串标志,该标志记录是否已分配给它。package mainimport (    "flag"    "fmt")type stringFlag struct {    set   bool    value string}func (sf *stringFlag) Set(x string) error {    sf.value = x    sf.set = true    return nil}func (sf *stringFlag) String() string {    return sf.value}var filename stringFlagfunc init() {    flag.Var(&filename, "filename", "the filename")}func main() {    flag.Parse()    if !filename.set {        fmt.Println("--filename not set")    } else {        fmt.Printf("--filename set to %q\n", filename.value)    }}下面是一些运行示例:$ go run a.go -filename=abc--filename set to "abc"$ go run a.go -filename=--filename set to ""$ go run a.go--filename not set

喵喵时光机

使用自定义标志类型(此线程中的 stringFlag 示例)的问题是您会稍微扰乱 PrintDefaults 输出(即 --help)。例如,使用字符串 username 标志和 stringFlag servername 标志,--help 如下所示:-server value    server:port (default localhost:1234)-username string    username (default "kimmi")请注意,就用户而言,这些都是字符串参数,但由于 stringFlag 不是字符串,因此呈现方式不同。flag的 Flagset 有一个内部映射,其中包括声明的标志(“正式”)和实际设置的标志(“实际”)。前者可通过 Lookup() 获得,可惜后者没有公开,或者您可以只写:var servername = flag.String("server", "localhost:8129", "server:port")flag.Parse()if f := flag.CommandLine.LookupActual("server"); f != nil {    fmt.Printf("server set to %#v\n", f)} else {    fmt.Printf("server not set\n")}如果您想要一致的 PrintDefaults() 输出,似乎您能做的最好的事情就是使用 Visit 来提取您自己的“实际”视图(VisitAll 对“正式”执行相同的操作):var servername = flag.String("server", "localhost:8129", "server:port")flag.Parse()flagset := make(map[string]bool)flag.Visit(func(f *flag.Flag) { flagset[f.Name]=true } )if flagset["server"] {    fmt.Printf("server set via flags\n")} else {    fmt.Printf("server not explicitly set, using default\n")}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go