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
}
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
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")
}
- 3 回答
- 0 关注
- 132 浏览
添加回答
举报