flag命令行参数解析

参考自 flag - 命令行参数解析 · Go语言标准库

1 golang 源文件分类

  • 命令源文件:package声明为main,有且只有一个main函数,会编译成可执行文件
  • 库源文件: package不能声明为main且不能包含main函数,会编译成库文件
  • 测试源文件:以_test.go结尾的文件,主要用来对其他源码的测试

2 命令源码文件基本介绍

  1. 定义:如果一个源码文件声明属于main包,并且包含一个无参数声明且无结果声明的main函数,那么则属于命令源码文件
  2. 用途:程序运行总入口

3 flag是做什么的

举个栗子,我们在执行很多脚本或者服务的时候,是期望能够指定参数的。

像php、python类脚本的命令参数就是直接跟在脚本后面

像nginx,bin这类,就会存在nginx -v 、nginx -c 、nginx -s reload 之类

那么golang类似nginx,也会有参数需求

4 实现一个根据入参决定输出的命令

任务名称:根据运行程序时给定的参数问候某人

代码如下:

package main

import fmt
import flag

var name string

func init() {
	flag.StringVar(&name, "name", "everyone", "greeting")
}

func main() {
	flag.Parse()
	fmt.Printf("hello, %s", name)
}

运行如下:

go run test.go -name=tudou

5 tips

5.1 定义flag的两种形式

1)flag.Xxx(),其中 Xxx 可以是 Int、String 等;返回一个相应类型的指针,如:

var name = flag.String("name", "everyone", "help message for name")

2)flag.StringVar(),将 flag 绑定到一个变量上,如:

var name int
flag.StringVar(&name, "name","everyone", "help message for name")

5.2 函数flag.StringVar的4个参数

  1. 第1个参数用于存储该命令参数值的地址
  2. 第2个参数是为了指定该命令参数的名称
  3. 第3个参数是为了指定在未追加该命令参数的默认值
  4. 第4个参数是该命令参数的简短说明

5.3 flag解析

在所有的 flag 定义完成之后,可以通过调用 flag.Parse() 进行解析。

命令行 flag 的语法有如下三种形式:

-flag // 只支持bool类型
-flag=x
-flag x // 只支持非bool类型

5.4 flag结构体

type Flag struct {
    Name     string // name as it appears on command line
    Usage    string // help message
    Value    Value  // value as set
    DefValue string // default value (as text); for usage message
}

5.5 命令解析何时终止

  • 第一个 non-flag 参数

当遇到单独的一个”-“或不是”-“开始时,会停止解析。

比如:./nginx - -c 或 ./nginx build -c

  • 两个连续的”- - “

比如:./nginx -c --

这里的”- -“会被当成是 c 的值

cobra 是 flag的升级版,经小伙伴提醒,在这里mark下 https://github.com/spf13/cobra