聊一聊Go編寫的命令列工具類

2021-10-04 02:34:25 字數 4518 閱讀 4899

go原生在flag包提供了乙個命令列工具類,它可以讓我們執行類似命令列的賦參操作,經常被運用於工具類,特別是資料處理過程,可以方便我們進行引數視覺化註解。

flag包提供了多個常用型別的賦值方法,如string, int, bool, float64, duration等。

下面列舉乙個簡單的例子。

用法示例:

func

main()

func

allright()

bool

我們通過command line 傳參給可執行程式,輸出:

$ ./tool.exe -word=hello -number=6

2020/03/18 10:59:49 flag for wordparam: hello

2020/03/18 10:59:49 flag for wordparam: 6

2020/03/18 10:59:49 flag for inner bool value :

false

如果使用-h/--help命令可以調出引數提示,輸出:

$ ./tool.exe -h

usage of e:\code\gowork\src\hellogo\basic\flag\tool.exe:

-number int

desc param 2 for integer number.

-okdesc value for boolean.

-word string

desc param 1 for something. (default "defaultvalue"

)

在實際應用環境,呼叫目標可能有多個,有時我們需要多個命令,多個引數聯合起來,用於呼叫不同的方法,類似於引數呼叫子命令的引數,

如:./cmd foo -a="a" -b=1或者./cmd bar -c="c" -d=2

subcommands

原生flag包提供了乙個子命令構造方式,newflagset用於返回子命令的flag,示例如下:

我們定義乙個解析子命令方法:

func

subcommands()

//引數邏輯呼叫, 使用分支語句

switch os.args[1]

}

$ ./tool.exe

expected 'foo' or 'bar' subcommands

usage of foo:

-fc string

foo sub value1 (default "default of fc"

) -fc2 string

foo sub value2 (default "default of fc2"

)usage of bar:

-bc string

bar sub b (default "default of bc"

)

命令呼叫示例:

$ ./tool.exe foo -fc=

"fc value" -fc2=

"fc22222"

2020/03/18 12:54:16 fc of foo: fc value

2020/03/18 12:54:16 fc2 of foo: fc22222

上述方式借助go的內建flag實現了命令傳參,但是有個問題,如上面提到,「在實際應用環境,呼叫目標可能有多個,有時我們需要多個命令」,對每個呼叫鏈都起乙個switch分支去寫可能十分吃力,我們自己能不能對呼叫鏈執行封裝,嘗試實現類似於flag的功能呢?

最近在預覽前輩的**塊中,發現乙個巧妙的實現方式,在go中,函式是可以作為引數傳入的,我們可以利用這一特性建立乙個方法鏈陣列,利用全域性函式變數根據入參進行呼叫,類似於物件導向語言裡面的多型,本質上是相同型別的不同表現。

程式例項:

/*

自定義方法呼叫

*///封裝命令結構, 指令/執行方法/提示

type cmd struct

//全域性指令陣列

var all [

]*cmd

wind實現:

//可變引數作為可選入參

func

process

(args ...

string

)//do something

logrus.

infof

("wind fly from %s, level %s."

, args[0]

, args[1]

)}//引數提示

func

usage()

string

sun實現:

func

process

(args ...

string

)//do something

logrus.

infof

("sun %s about %s miles."

, args[0]

, args[1]

)}//引數提示

func

usage()

string

至此, 不同指令的表現就實現完了,有點類似於物件導向語言裡面的多型,本質上是相同型別的不同表現。

後面我們來看下在main方法怎麼呼叫

func

init()

) all =

(all,

&cmd)}

//全域性用法

func

usage()

string

return sb.

string()

}func

main()

} fmt.

fprintf

(os.stderr,

"no match func for %s.\n"

, os.args[1]

)}fmt.

fprintln

(os.stderr,

usage()

)}

我們利用入參的長度以及內建命令區分呼叫鏈,對符合格式的引數與全域性指令切片進行匹配。

下面是輸出示例:

$ ./tool.exe -h

usage: e:\code\gowork\src\hellogo\basic\flag\tool.exe

[args...]

命令: sun, 用法: hint: sun

命令: wind, 用法: hint: wind

$ ./tool.exe a b

no match func for a.

usage: e:\code\gowork\src\hellogo\basic\flag\tool.exe

[args...]

命令: sun, 用法: hint: sun

命令: wind, 用法: hint: wind

可以看到當引數不合法時會遍歷列印各個子命令的用法給予提示。

$ ./tool.exe sun

time=

"2020-03-18t15:23:23+08:00" level=error msg=

"hint: sun "

常規呼叫:

$ ./tool.exe wind n 7

time=

"2020-03-18t15:22:40+08:00" level=info msg=

"wind fly from n, level 7."

$ ./tool.exe sun rise 30

time=

"2020-03-18t15:24:28+08:00" level=info msg=

"sun rise about 30 miles."

以上是go命令列工具的簡單用法,內建的flag幫我們封裝好了一下基礎函式,我們也可以利用字串處理自定義實現工具類,相容多種場景,簡單的邏輯判斷也能達到flag的那種用法。

git project

go by example: command-line subcommands

command line flag syntax

聊一聊go的協程

最近在學習go語言,學習到了協程,來記錄下學習的心路歷程 先來看下例子 列印5個hello和5個world package main func say s string func main go 啟動協程的方式就是使用關鍵字 go,後面一般接乙個函式或者匿名函式 執行上述 發現什麼也沒有輸出 為什麼...

Go命令列工具

ubuntu安裝配置好go環境後,終端執行 go 則會顯示出一些常用命令。其中有一些是在編譯安裝信令伺服器時使用到的。執行 go 後,go command arguments the commands are build compile packages and dependencies clean...

Go語言命令列工具介紹 3

用於編譯原始碼檔案 包 依賴包 1.1 編寫源 test.gopackage main import fmt time func main 1.2 執行 go buildgo build test.go將 test.go 源 編譯完成之後,src目錄下會新增編譯完成之後的test可執行檔案,如下圖所...