【问题标题】:Golang conflicting command line flagsGolang冲突的命令行标志
【发布时间】:2012-12-05 04:41:39
【问题描述】:

我在使用 gocheck 运行测试时遇到问题。我需要传递一个标志来指定要运行的测试,例如go test -gocheck.f ApiSuite.TestSomeFunction.

我的测试文件导入了一个设置包,其中有一个init() 函数,它指定了自己的标志并调用flag.parseFlags()。我遇到的问题是这似乎覆盖了 gocheck 标志,所以我收到一个错误,即标志 -gocheck.f 无法识别。

注意:不确定这是否相关,但它只发生在我的一些包中而不是其他包中。我认为这只是基于 go 决定导入包的顺序,但我想我会提到它以防万一。

还有其他人遇到过这个问题吗?有没有一种简单的方法可以让所有标志组合起来而不会被破坏,或者让 gocheck 标志优先于我的自定义标志?

【问题讨论】:

    标签: go


    【解决方案1】:

    如果多个包调用 flag.Parse 而不担心其他包定义其他标志,那么你就有麻烦了(正如你已经经历过的那样)。 “标志”包的状态是一个全局状态,所以它或多或少是相同的,就好像不同的包会在初始化期间竞争将全局变量的值设置为不同的值。显然,这可能不会很好地结束。

    防止这种情况的简单方法:flag.Parse 应该只被调用一次(在第一个近似值中)。这就是为什么它通常只出现在包“main”中的原因。如果您的非主包调用flag.Parse,那么它通常会与包“main”中调用的任何flag.Parse 冲突。请注意,go test 合成了一个 package main 以测试一个包,而 flag.Parse 从合成的“主”包中调用的。

    另一方面,只在非主包中定义标志并依赖flag.Parse 将在包“主”中调用更“安全”(但无论如何都可能发生冲突)。在非主包中,然后可以验证flag.Parse 是否已通过使用flag.Parsed() 调用。

    上面写的简化的。有关其他选项,请检查包标志 documentation。在某些情况下,可以通过例如使用flag.Flagset 来获得更多“权力”,即通过使用 local 状态作为包中的标志选项。

    但是,我个人不喜欢以任何方式在包“main”之外使用包“标志”,而是通过其 API 设置任何可配置的包行为。但是,确实存在例外,例如在 *_test 文件或其他特殊情况下。

    【讨论】:

    • 谢谢。实际上,我通过将 gocheck 匿名导入我的设置文件,通过反复试验修复了代码,现在所有标志一起工作。在阅读了您的答案并查看了 gocheck 源代码之后,我明白了为什么会这样 - gocheck 从不调用 flag.Parse(),所以我只需要确保在调用我的 settings.init() 方法之前导入 gocheck 并且所有标志都会一起工作。很好的建议,虽然只在 main 中解析标志,但我会记住这一点,以备将来使用。
    猜你喜欢
    • 2015-08-27
    • 1970-01-01
    • 1970-01-01
    • 2011-12-19
    • 2011-11-06
    • 2013-11-14
    • 1970-01-01
    • 2021-07-09
    • 1970-01-01
    相关资源
    最近更新 更多