Go常見問題:command-line-argument: ***: undefined: ***

我們通常在go代碼時,通常採用idea或者命令行的形式進行編譯和運行,這兩天我遇到一個非常困惑的問題,一直沒找到具體原因,已經做了快一年的go程序員,看見這個問題甚是臉疼。

問題描述

在開發代碼過程中,經常會因爲邏輯處理而對代碼進行分類,放進不同的文件裏面;像這樣,同一個包下的兩個文件,點擊idea的運行按鈕或者運行 go run main.go命令時,會報出如下錯誤,詳情見圖:

command-line-arguments

src/demo/main/main.go:4:2: undefined: demo

Compilation finished with exit code 2

在這裏插入圖片描述
但是輸入 go build,之後當前目錄下會生成一個二進制文件,執行後會發現輸出正確結果:
在這裏插入圖片描述

問題分析:

通過操作發現,輸入go run main.go會執行失敗,輸入go build,在運行二進制文件可以成功,然後開始分析go源代碼,找到執行命令的入口。
在這裏插入圖片描述
在源代碼的main函數中,我們發現從base.Commands的切片中獲取要執行的命令,然後和傳入的args一起執行cmd.Run(cmd, args)這個方法;

在這裏插入圖片描述
在這裏插入圖片描述
然後再回過頭看cmd.Run(cmd, args)這個函數,結果發現它只是定義了一種類型,具體實現這裏沒有指出;
在這裏插入圖片描述
緊接着回頭去看run包下的函數,會發現run.go在初始化的時候,會把改文件下的runRun()函數賦值給base.Command{}定義的對象CmdRun,結果會發現runRun函數的的參數類型和個數完全符合cmd.Run(cmd, args)這個函數類型,在go語言中,函數的參數類型和參數個數符合定義的函數類型,則說明改函數實現了定義函數(注:go語言中,函數與方法不同)

run.go詳情
在runRun()函數中,會發現files和cmdArgs接收的是傳過來的文件列表,然後會通過GoFilesPackage(files),然後會入棧、加載、出棧等操作,由於啓動的時候傳遞的只是一個.go文件,並沒有傳遞demo.go,所以系統在加載main.go文件中並沒有找到demo.go文件中定義的變量,則在p := load.GoFilesPackage(files)這一行,開始出錯。

正確操作:

該出錯原因屬於go的多文件加載問題,採用go run命令執行的時候,需要把待加載的.go文件都包含到參數裏面,正確操作如下圖所示:

在這裏插入圖片描述

發佈了254 篇原創文章 · 獲贊 71 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章