golang编程之package flag解析入参

前端之家收集整理的这篇文章主要介绍了golang编程之package flag解析入参前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

我们随便写一个日常使用的psql的命令行用法

view sourceprint?

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

2.server starting @H_502_16@@H_502_16@

这种情况下我们更需要的是解析各个参数的意义,比如-D选项 是通知pg_ctl pgdata的路径在那,-l选项告知的是log记录到那个文件,start相当于子命令,告知action。对于这种命令,我们都知道C语言有getopt及其getopt_long来解决。go语言怎么解决
go语言提供了flag这个package。来应对这种入参的解析。
flag支持的语言格式如下:

-flag // bool类型only
-flag=x
-flag x //not bool 类型
很自然,这个flag能够解析 -D /home/manu/DB_data,对应第二种类型,我们知道pg_ctl有-W选项,属于一个开关性质的bool型的选项


view sourceprint?

1.-W do not wait until operation completes @H_502_16@@H_502_16@

自然对应第一种类型,也可以解析。第二种也很好理解。
下面我给出一个例子,简单的解析这个pg_ctl的命令:

view sourceprint?

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

02. @H_502_16@@H_502_16@

03. @H_502_16@@H_502_16@

04.package main@H_502_16@@H_502_16@

05.import (@H_502_16@@H_502_16@

06. "fmt"@H_502_16@@H_502_16@

07. "flag"@H_502_16@@H_502_16@

08.)@H_502_16@@H_502_16@

09. @H_502_16@@H_502_16@

10.func main(){@H_502_16@@H_502_16@

11. @H_502_16@@H_502_16@

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

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

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

15. @H_502_16@@H_502_16@

16. flag.Parse()@H_502_16@@H_502_16@

17. @H_502_16@@H_502_16@

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

19. @H_502_16@@H_502_16@

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

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

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

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

24. @H_502_16@@H_502_16@

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

26. @H_502_16@@H_502_16@

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

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

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

30. }@H_502_16@@H_502_16@

31. @H_502_16@@H_502_16@

32. @H_502_16@@H_502_16@

33.} @H_502_16@@H_502_16@

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@H_502_16@@H_502_16@

02.action : start@H_502_16@@H_502_16@

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

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

05.nowait : true@H_502_16@@H_502_16@

06.-------------------------------------------------------@H_502_16@@H_502_16@

07.there are 1 non-flag input param@H_502_16@@H_502_16@

08.#0 :start@H_502_16@@H_502_16@

09. @H_502_16@@H_502_16@

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@H_502_16@@H_502_16@

11.action : start@H_502_16@@H_502_16@

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

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

14.nowait : true@H_502_16@@H_502_16@

15.-------------------------------------------------------@H_502_16@@H_502_16@

16.there are 1 non-flag input param@H_502_16@@H_502_16@

17.#0 :start@H_502_16@@H_502_16@

我们看到了,解析出了data_path,log_file无论 -l -D出现的顺序如何,只要正常的出现了,就能正常的解析。
但是晴朗的天空中也有一片乌云,start不是这种 -key=alue 或则-option的类型,flag是解析不了的。我们称这种参数为non-flag参数,flag解析遇到non-flag参数就停止了:

view sourceprint?

1.s := f.args[0]@H_502_16@@H_502_16@

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

3. return false,nil@H_502_16@@H_502_16@

4.} @H_502_16@@H_502_16@

所以如果我们将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/ @H_502_16@@H_502_16@

02.action : start@H_502_16@@H_502_16@

03.data path: /home/manu/sample@H_502_16@@H_502_16@

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

05.nowait : false@H_502_16@@H_502_16@

06.-------------------------------------------------------@H_502_16@@H_502_16@

07.there are 5 non-flag input param@H_502_16@@H_502_16@

08.#0 :start@H_502_16@@H_502_16@

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

10.#2 :-W@H_502_16@@H_502_16@

11.#3 :-D@H_502_16@@H_502_16@

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

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())@H_502_16@@H_502_16@

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

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

4. } @H_502_16@@H_502_16@

flag还提供了NFlag()获取那些匹配上的参数的个数。 从例子上看,flag package很有用,但是并没有强大到解析一切的程度。 如果你有类似-option或者-key =value这种参数,不妨试试 flag。如果你的入参解析非常复杂,flag可能捉襟见肘。

猜你在找的Go相关文章