为了账号安全,请及时绑定邮箱和手机立即绑定

检查 Go 中是否提供了标志

检查 Go 中是否提供了标志

Go
慕运维8079593 2021-12-20 15:07:30
用flag包,有没有什么好办法区分是否传入了字符串flag?比如没有传递flag的时候,我想设置一个动态的默认值。但是,如果提供了标志但值为"".目前我正在做以下事情:flagHost = flag.String(flagHostFlagKey, "", "...")...setHostname := falsefor _, arg := range os.Args {    if arg == "-"+flagHostFlagKey {        setHostname = true    }}if !setHostname {     ...这似乎工作正常,但有点丑陋。在使用标准标志包的同时还有更好的方法吗?
查看完整描述

3 回答

?
白猪掌柜的

TA贡献1893条经验 获得超10个赞

使用flag.Visit()函数:


func isFlagPassed(name string) bool {

    found := false

    flag.Visit(func(f *flag.Flag) {

        if f.Name == name {

            found = true

        }

    })

    return found

}


查看完整回答
反对 回复 2021-12-20
?
慕虎7371278

TA贡献1802条经验 获得超4个赞

内置标志类型不支持区分默认值和对默认值的显式分配。但是,该flag包非常灵活,并允许您使用flag.Value接口滚动自己的类型。


这是一个完整的示例,其中包含一个字符串标志,该标志记录是否已分配给它。


package main


import (

    "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 stringFlag


func 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


查看完整回答
反对 回复 2021-12-20
?
喵喵时光机

TA贡献1846条经验 获得超7个赞

使用自定义标志类型(此线程中的 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")

}


查看完整回答
反对 回复 2021-12-20
  • 3 回答
  • 0 关注
  • 132 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信