典型回答
通過構建或安裝命令原始碼檔案生成的可執行檔案就可以被視為「命令」,既然是命令,那麼就應該具備接收引數的能力。
例如,要實現
根據執行程式時給定的引數問候某人
**
package main
import (
"flag"
// [1]
"fmt"
)var name string
func init()
func main()
解析[1]匯入flag包,這是go 語言標準庫中專門用於接收和解析命令引數的包。
[2]設定命令引數
接受 4 個引數。
還有乙個與flag.stringvar函式類似的函式,叫flag.string。
這兩個函式的區別是,後者會直接返回乙個已經分配好的用於儲存命令引數值的位址。
var name = flag.
string("name", "everyone", "the greeting object.")
這裡的name保持的就是位址
[3]用於真正解析命令引數,並把它們的值賦給相應的變數。
因此最好把flag.parse()放在main函式的函式體的第一行。
檢視該命令原始碼檔案的引數說明,–help:
像上面這一串/tmp/go-build343904153/b001/exe/demo1
**
這是命令構建上述命令原始碼檔案時臨時生成的可執行檔案的完整路徑。
如果我們先構建這個命令原始碼檔案再執行生成的可執行檔案,就會這樣:
這有很多種方式,最簡單的一種方式就是對變數flag.usag重新賦值。
flag.usage的型別是func(),即一種無引數宣告且無結果宣告的函式型別。
注意,對flag.usage的賦值必須在呼叫flag.parse函式之前
**
import (
"flag"
// [1]
"fmt"
"os"
)var name string
func init()
func main()
flag.parse() // [3]
fmt.printf("hello, %s!\n", name)
}
執行
現在再深入一層,我們在呼叫flag包中的一些函式(比如stringvar、parse等等)的時候,實際上是在呼叫flag.commandline變數的對應方法。
flag.commandline相當於預設情況下的命令引數容器。所以,通過對flag.commandline重新賦值,我們可以更深層次地定製當前命令原始碼檔案的引數使用說明。
現在我們把main函式體中的那條對flag.usage變數的賦值語句登出掉,然後在init函式體的開始處新增如下**:
flag.commandline = flag.newflagset("", flag.exitonerror)
flag.commandline
.usage = func()
執行go run demo.go –help後,其輸出會與上一次的輸出的一致。不過後面這種定製的方法更加靈活。比如,當我們把為flag.commandline賦值的那條語句改為
flag.commandline = flag.newflagset("", flag.paniconerror)
執行結果
會產生另一種輸出效果。
這是由於我們在這裡傳給flag.newflagset函式的第二個引數值是flag.paniconerror。
flag.paniconerror和flag.exitonerror都是預定義在flag包中的常量。
flag.exitonerror的含義是,告訴命令引數容器,當命令後跟–help或者引數設定的不正確的時候,在列印命令引數使用說明後以狀態碼2結束當前程式。
狀態碼2代表使用者錯誤地使用了命令,而flag.paniconerror與之的區別是在最後丟擲「執行時恐慌(panic)」。
上述兩種情況都會在我們呼叫flag.parse函式時被觸發。
執行時恐慌」是 go 程式錯誤處理方面的概念
在函式外再新增乙個變數宣告:
var cmdline = flag.newflagset("question", flag.exitonerror)
完整**
package main
import (
"flag"
// [1]
"fmt"
"os"
)var name string
var cmdline = flag.newflagset("", flag.exitonerror)
func init()
cmdline.stringvar(&name, "name", "everyone", "the greeting object.") // [2]
}func main()
其中的os.args[1:]指的就是我們給定的那些命令引數。這樣做就完全脫離了flag.commandline。
這樣更加靈活定製命令引數容器,並且完全不會影響到那個全域性變數flag.commandline。
int(int|int64|uint|uint64),
float(float|float64)
string,
bool,
duration(時間),
var(自定義)
關鍵就是使用flag.var(),關鍵點在於需要實現flag包的value介面。
go 命令原始碼檔案
如果乙個原始碼檔案宣告屬於main包,並且包含乙個無引數宣告且無結果宣告的 main 函式,那麼它就是命令原始碼檔案。package main import fmt func main 根據執行程式時根據給定的引數問候某人 package main import flag 接收和解析命令引數 fmt...
Go 筆記三 庫原始碼檔案
庫原始碼檔案不能被直接執行,它僅用於存放程式實體。只要遵從 go 語言規範,這些程式實體就可以被其他 使用。在 go 語言中,它是變數 常量 函式 結構體和介面的統稱。第一條規則,同目錄下的原始碼檔案的 包宣告語句要一致。也就是說,它們要同屬於乙個 包。這對於所有原始碼檔案都是適用的。第二條規則,原...
go原始碼解讀(二)
solve the 2,3,5 problem print all numbers with 2,3,or 5 as factor using channels.使用通道解決2,3,5問題 以2 3或5為因子列印所有數字 test the solution,silently.測試解決方案。packa...