如何访问主包外的标志?

Ame*_*mer 4 flags go

当然,我们在main.go中解析主要包中的标志.然后我们有另一个包,我们想要读取一些标志的值.

flags.Args()工作正常,它将返回所有非标志值.

但我无法弄清楚如何读取已经解析的值除了main之外的包中的标志.

可能吗?

谢谢

阿梅尔

And*_*ski 10

我最近有同样的要求,我想要一个避免flag.Parseinit函数中反复调用的解决方案.

仔细阅读我发现的标志Lookup(name string),它返回一个具有ValueFlag.每个内置的Value都实现了接口.调用链如下所示:flag.Getter

flag.Lookup("httplog").Value.(flag.Getter).Get().(bool)
Run Code Online (Sandbox Code Playgroud)

如果您错误输入标志名称或使用错误的类型,则会出现运行时错误.我将查找包装在一个函数中,我直接在需要的地方调用,因为查找和get方法很快,而且函数不经常调用.所以主包声明了标志.

// main.go
package main

import "flag"

var httplog = flag.Bool("httplog", false, "Log every HTTP request and response.")

func main() {
    flag.Parse()
    // ...
}
Run Code Online (Sandbox Code Playgroud)

除了标志名称之外,与main解耦的实用程序包读取标志值.

// httpdiag.go
package utility

import "flag"

func logging() bool {
    return flag.Lookup("httplog").Value.(flag.Getter).Get().(bool)
}
Run Code Online (Sandbox Code Playgroud)


One*_*One 6

您可以在该包中定义标志并调用flag.Parse()func init()可以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
    }
}
Run Code Online (Sandbox Code Playgroud)

FlagSet.Parse(os.Args)如果你想重新解析参数,你也可以使用。


小智 6

您可以定义var将标志存储在单独的包中,作为导出变量,然后调用主包中的标志解析以使用该变量,如下所示:

mypackage/const.go

var (
    MyExportedVar string
)
Run Code Online (Sandbox Code Playgroud)

主包/main.go

func init() {
    flag.StringVar(&mypackage.MyExportedVar, "flagName", "defaultValue", "usage")

    flag.Parse()
}
Run Code Online (Sandbox Code Playgroud)

这样,每个人都可以访问该标志,包括该包本身。

注意:这仅适用于导出的变量。