【发布时间】:2017-05-16 17:00:51
【问题描述】:
我们在 main.go 中 parse flags 当然是在 main 包中。然后我们有另一个包,我们想在其中读取一些标志的值。
flags.Args() 工作正常,它将返回所有非标志值。
但我无法弄清楚如何读取除 main 之外的包中标志的已解析值。
有可能吗?
谢谢
美国
【问题讨论】:
我们在 main.go 中 parse flags 当然是在 main 包中。然后我们有另一个包,我们想在其中读取一些标志的值。
flags.Args() 工作正常,它将返回所有非标志值。
但我无法弄清楚如何读取除 main 之外的包中标志的已解析值。
有可能吗?
谢谢
美国
【问题讨论】:
我最近有同样的需求,我想要一个避免在 init 函数中重复调用 flag.Parse 的解决方案。
仔细阅读flag 包,我发现Lookup(name string) 返回一个Flag,它有一个Value。每个内置的 Value 都实现了flag.Getter 接口。调用链如下所示:
flag.Lookup("httplog").Value.(flag.Getter).Get().(bool)
如果您输入错误的标志名称或使用错误的类型,您会收到运行时错误。我将查找包装在一个函数中,我在需要的地方直接调用该函数,因为查找和获取方法很快,而且该函数不经常调用。所以主包声明了这个标志。
// main.go
package main
import "flag"
var httplog = flag.Bool("httplog", false, "Log every HTTP request and response.")
func main() {
flag.Parse()
// ...
}
而除了标志名之外与main解耦的实用程序包读取标志值。
// httpdiag.go
package utility
import "flag"
func logging() bool {
return flag.Lookup("httplog").Value.(flag.Getter).Get().(bool)
}
【讨论】:
您可以将存储标志的var定义在单独的包中,作为导出变量,然后在主包中调用标志解析来使用该变量,如下所示:
mypackage/const.go
var (
MyExportedVar string
)
mainpackage/main.go
func init() {
flag.StringVar(&mypackage.MyExportedVar, "flagName", "defaultValue", "usage")
flag.Parse()
}
这样,每个人都可以访问该标志,包括该包本身。
注意: 这仅适用于导出的变量。
【讨论】:
您可以在该包中定义标志并在func init()中调用flag.Parse(),flag.Parse可以被多次调用。
但是,如果你想从多个包中访问标志的值,你必须公开它或创建一个公开的函数来检查它。
例如:
// pkgA
var A = flag.Bool("a", false, "why a?")
func init() {
flag.Parse()
}
// main package
func main() {
flag.Parse()
if *pkgA.A {
// stuff
}
}
如果你想重新解析参数,也可以使用FlagSet.Parse(os.Args)。
【讨论】:
当你解析你的标志时,将它们解析成以初始大写开头的全局变量,因此它们是公共的,例如
package main
var Species = flag.String("species", "gopher", "the species we are studying")
func main() {
flag.Parse()
}
然后在您的其他包中,您可以将它们称为
package other
import "/path/to/package/main"
func Whatever() {
fmt.Println(main.Species)
}
【讨论】:
import cycle not allowed 那是因为其他包在主文件夹下。
pkg.New(flag-value)。
flag.Args() 是要走的路。谢谢@OneOfOne 和尼克!