1 回答
TA贡献1842条经验 获得超13个赞
正如上面评论中所写,没有工具可以做到这一点。
但是您可以使用一个简单的技巧来找出答案。
你想注册一个标志,但你不能,因为它已经在其他地方(未知位置)注册过。
如果可以先注册,则报错时会报当前注册的地方。
怎么做?创建一个注册此标志的包:
package first
import "flag"
func init() {
flag.String("tf", "", "")
}
然后像这样在你的包中首先导入这个包main:
package main
import _ "play.gorund/first"
import (
"flag"
"play.ground/foo"
)
会发生什么?首先执行包init(),first正确注册tf标志,然后foo将尝试再次执行该操作,失败并报告错误。
示例输出(在Go Playground上尝试):
/tmpfs/play flag redefined: tf
panic: /tmpfs/play flag redefined: tf
goroutine 1 [running]:
flag.(*FlagSet).Var(0xc000062180, {0x4c3188, 0xc0000142a0}, {0x4a2642, 0x2}, {0x0, 0x0})
/usr/local/go-faketime/src/flag/flag.go:980 +0x2f9
flag.StringVar(...)
/usr/local/go-faketime/src/flag/flag.go:851
play.ground/foo.init.0()
/tmp/sandbox1464715048/foo/foo.go:10 +0x7d
如您所见,foo.go第 10 行注册了tf标志。任务完成。
笔记:
许多编辑器在保存时自动设置格式,这可能涉及重新排列/重新组合导入,因此您的play.ground/first导入可能会向下移动,而不是第一个。为避免这种情况,请勿使用自动格式化功能,或为此包选择一个在自动格式化后将首先保留的名称。
笔记2:
Spec: Package initialization声明了初始化包的要求和规则,并没有指定处理导入的顺序(唯一保证的是所有引用的包在使用之前都会被递归初始化)。这意味着尽管当前的编译器按照列出的方式处理它们,但您不能 100% 依赖它。还有一个问题,即使是main包也有多个源文件,以不同的顺序向编译器提供它们也可能会改变初始化顺序。该规范将此作为“建议”:
为了确保可重现的初始化行为,鼓励构建系统以词法文件名顺序向编译器呈现属于同一包的多个文件。
- 1 回答
- 0 关注
- 214 浏览
添加回答
举报
