Golang冲突的命令行标志

dan*_*nny 11 go

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

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

注意:不确定这是否相关,但它只发生在我的一些软件包而不是其他软件包中.我假设它只是基于订单决定导入包,但我想如果这是相关的我会提到它.

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

zzz*_*zzz 14

如果多个包调用flag.Parse而不关心定义其他标志的其他包那么你就遇到麻烦了(正如你已经体验过的那样)."flag"包的状态是一个全局状态,因此它或多或少相同,就好像不同的包将竞争在init期间将全局变量的值设置为不同的值.显然,这可能不会很好.

防止这种情况的简单方法:flag.Parse应该只调用一次(在第一次近似中).这就是为什么它通常只在包"main"中看到.如果您的非主程序包调用,flag.Parse那么它通常会与任何flag.Parse被调用的程序包"main" 冲突.注意,go test合成一个package main以便测试包和flag.Parse 从该合成"主"包调用.

另一方面,它更"安全"(但无论如何都可能发生冲突)只在非主包中定义标志并依赖于flag.Parse在包"main"中调用.在非主程序包中,可以flag.Parse使用flag.Parsed()验证是否已调用该程序包.

上面写的简化的.有关其他选项,请查看包标志文档.在某些情况下可以通过使用flag.Flagset获得更多"功率" ,即通过使用包内的标志选项的本地状态.

但是,我个人不希望以任何方式在包"main"之外使用包"flag",而是通过其API设置任何可配置包行为.但是,确实存在例外情况,例如*_test文件或其他特殊情况.

  • 谢谢.我实际上通过匿名导入gocheck到我的设置文件中,通过试验和错误修复了代码,现在所有的标记一起工作.在阅读完答案并查看gocheck源代码后,我明白了为什么这样做 - gocheck从不调用flag.Parse(),所以我必须确保在调用settings.init()方法之前导入gocheck并且所有标志都将一起工作.虽然关于仅在主要解析标志的好建议,但我会记住未来. (2认同)