golang編程之package flag解析入參

 咱們隨便寫一個平常使用的psql的命令行用法
html

view sourceprint?sql

1.manu@manu-hacks:~$ pg_ctl -D /home/manu/DB_data/ -l /home/manu/DB_data/postgres_manu.log   start post

2.server starting spa

這種狀況下咱們更須要的是解析各個參數的意義,好比-D選項 是通知pg_ctl pgdata的路徑在那,-l選項告知的是log記錄到那個文件,start至關於子命令,告知action。對於這種命令,咱們都知道C語言有getopt及其getopt_long來解決。go語言怎麼解決?
   go語言提供了flag這個package。來應對這種入參的解析。
   flag支持的語言格式以下:.net

-flag     // bool類型only
   -flag=x
   -flag x  //not bool 類型
   很天然,這個flag可以解析 -D /home/manu/DB_data,對應第二種類型,咱們知道pg_ctl有-W選項,屬於一個開關性質的bool型的選項命令行


view sourceprint?code

1.-W do not wait until operation completes server

天然對應第一種類型,也能夠解析。第二種也很好理解。
   下面我給出一個例子,簡單的解析這個pg_ctl的命令:
htm

view sourceprint?字符串

01.manu@manu-hacks:~/code/go/self$ cat pg_ctl_parse.go

02.

03.

04.package main

05.import (

06.    "fmt"

07.    "flag"

08.)

09.

10.func main(){

11.

12.    data_path := flag.String("D","/home/manu/sample/","DB data path")

13.    log_file := flag.String("l","/home/manu/sample.log","log file")

14.    nowait_flag :=flag.Bool("W",false,"do not wait until operation completes")

15.

16.    flag.Parse()

17.

18.    var cmd string = flag.Arg(0);

19.

20.    fmt.Printf("action   : %s\n",cmd)

21.    fmt.Printf("data path: %s\n",*data_path)

22.    fmt.Printf("log file : %s\n",*log_file)

23.    fmt.Printf("nowait     : %v\n",*nowait_flag)

24.

25.    fmt.Printf("-------------------------------------------------------\n")

26.

27.    fmt.Printf("there are %d non-flag input param\n",flag.NArg())

28.    for i,param := range flag.Args(){

29.        fmt.Printf("#%d    :%s\n",i,param)

30.    }

31.

32.

33.}

OK,咱們分析下代碼(分割線下面的咱們暫時不看):
   第一行對應的是data_path的解析規則
   -D選項對應的值是字符串類型字符串,
   默認值是「/home/manu/sample」,
   DB data path提示信息或者help信息或者說明是。

view sourceprint?

01.manu@manu-hacks:~/code/go/self$ go run pg_ctl_parse.go  -D /home/manu/DB_data/ -l /home/manu/DB_data/postgres_manu.log -W start

02.action   : start

03.data path: /home/manu/DB_data/

04.log file : /home/manu/DB_data/postgres_manu.log

05.nowait : true

06.-------------------------------------------------------

07.there are 1 non-flag input param

08.#0 :start

09.

10.manu@manu-hacks:~/code/go/self$ go run pg_ctl_parse.go   -l=/home/manu/DB_data/postgres_manu.log -W -D /home/manu/DB_data/  start

11.action   : start

12.data path: /home/manu/DB_data/

13.log file : /home/manu/DB_data/postgres_manu.log

14.nowait : true

15.-------------------------------------------------------

16.there are 1 non-flag input param

17.#0 :start

咱們看到了,解析出了data_path,log_file不管 -l -D出現的順序如何,只要正常的出現了,就能正常的解析。
   可是晴朗的天空中也有一片烏雲,start不是這種 -key=alue 或則-option的類型,flag是解析不了的。咱們稱這種參數爲non-flag參數,flag解析遇到non-flag參數就中止了:

view sourceprint?

1.s := f.args[0]

2.if len(s) == 0 || s[0] != '-' || len(s) == 1 {

3.    return false, nil

4.}

因此若是咱們將non-flag參數放在最前面,flag什麼也不會解析,由於flag遇到了這個就中止解析了。

view sourceprint?

01.manu@manu-hacks:~/code/go/self$ go run pg_ctl_parse.go  start -l=/home/manu/DB_data/postgres_manu.log -W -D /home/manu/DB_data/  

02.action   : start

03.data path: /home/manu/sample

04.log file : /home/manu/sample.log

05.nowait   : false

06.-------------------------------------------------------

07.there are 5 non-flag input param

08.#0 :start

09.#1 :-l=/home/manu/DB_data/postgres_manu.log

10.#2 :-W

11.#3 :-D

12.#4 :/home/manu/DB_data/

OK,flag提供了Arg(i),Args()來獲取non-flag參數,NArg()來獲取non-flag的個數。正如咱們們sample 代碼看到的。  

view sourceprint?

1.fmt.Printf("there are %d non-flag input param\n",flag.NArg())

2.    for i,param := range flag.Args(){

3.        fmt.Printf("#%d :%s\n",i,param)

4.    }

flag還提供了NFlag()獲取那些匹配上的參數的個數。    從例子上看,flag package頗有用,可是並無強大到解析一切的程度。    若是你有相似-option或者-key =value這種參數,不妨試試 flag。若是你的入參解析很是複雜,flag可能捉襟見肘。

相關文章
相關標籤/搜索