代码之家  ›  专栏  ›  技术社区  ›  Nitzan

有没有一种方法可以确定在使用“flag.visitall”时是否设置了标志?

go
  •  3
  • Nitzan  · 技术社区  · 7 年前

    我用的是Go's Native "flag" 包裹。

    它内置的功能是访问当前定义的所有标志,使用 flag.VisitAll .

    我正在尝试构建一个代码段,该代码段试图从一个环境变量(如果存在)中获取该标志的值,以防未设置该标志,并且我找不到确定是否设置了特定标志的方法。

    在不实现新参数类型的情况下,是否有任何方法可以实现这一点?

    2 回复  |  直到 7 年前
        1
  •  0
  •   Tim Cooper    7 年前

    没有函数可以遍历未设置的命令行标志。但是,可以通过使用返回的标志之间的差异来复制此功能 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)
    }
    
        2
  •  2
  •   Martin Gallagher    7 年前

    使用 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)
    }
    

    见: https://play.golang.org/p/ixDsXH31cBF