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 關注
- 155 瀏覽
添加回答
舉報