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

时间:2018-10-21 10:03:12

标签: go

我正在使用go的本机"flag"包。

其中内置了使用flag.VisitAll访问所有当前定义的标志的功能。

我正在尝试构建一个片段,尝试从环境变量中获取该标志的值(如果存在)并且万一未设置该标志的情况,并且我无法找到一种方法来确定是否特定标记是否已设置。

有什么方法可以实现而无需实现新的参数类型?

2 个答案:

答案 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)
}

请参阅:https://play.golang.org/p/ixDsXH31cBF

答案 1 :(得分:0)

没有任何功能可以遍历未设置的命令行标志。但是,可以通过利用VisitAllVisit返回的标志之间的差异来复制此功能。前者遍历所有标志,而后者遍历设置的标志:

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