Go 学习笔记(45)— Go 标准库之 flag(命令行参数解析)
1. 参数解析说明
import "flag"
flag
包实现了命令行参数的解析。每个参数认为一条记录,根据实际进行定义,到一个 set
集合。每条都有各自的状态参数。
使用 flag
的正常流程为:
- 通过
flag.String()
,flag.Bool()
,flag.Int()
等函数来定义命令行中需要使用的参数; - 在定义完
flag
命令行参数后,通过调用flag.Parse()
来进行对命令行参数的解析; - 获取
flag.String()
,flag.Bool()
,flag.Int()
等方法的返回值,即对应用户输入的参数;
需要注意的是:
flag.Xxx()
返回的值是变量的内存地址,要获取值时要通过在变量前加*
获取。
flag.Int
、 flag.Bool
、 flag.String
这样的函数格式都是一样的,调用的时候需要传入 3 个参数
func Int(name string, value int, usage string) *int
func Bool(name string, value bool, usage string) *bool
func String(name string, value string, usage string) *string
name
表示命令行参数的名称, value
表示命令行参数的值, usage
表示命令行参数的说明和描述。
其它可注册的 flag
类型有:
Bool / Int / Int64 / Uint / Uint64 / Float / Float64 / String / Duration / Var
最简单的代码示例:
package main// 导入系统包
import ("flag""fmt"
)// 定义命令行参数
var mode = flag.String("mode", "", "process mode")
var num = flag.Int("num", 5, "process number")
var isProcess = flag.Bool("isProcess", true, "process bool")func main() {// 解析命令行参数flag.Parse()// 输出命令行参数fmt.Println(*mode)fmt.Println(*num)fmt.Println(*isProcess)
}
运行结果:
wohu@wohu:~/gocode/src$ go run hello.go -h
Usage of /tmp/go-build314506183/b001/exe/hello:-isProcessprocess bool (default true)-mode stringprocess mode-num intprocess number (default 5)
exit status 2
wohu@wohu:~/gocode/src$ go run hello.go -mode="hello,world" -num=10
hello,world
10
true
wohu@wohu:~/gocode/src$
命令行 flag
语法:
-flag
-flag=x
-flag x // 只有非bool类型的flag可以
可以使用 1 个或 2 个 -
号,效果是一样的。最后一种格式不能用于 bool
类型的 flag
,因为如果有文件名为 0、 false
等时,如下命令:
cmd -x *
其含义会改变。你必须使用 -flag=false
格式来关闭一个 bool
类型 flag
。
整数flag接受1234、0664、0x1234等类型,也可以是负数。bool类型flag可以是:
1, 0, t, f, T, F, true, false, TRUE, FALSE, True, False
注意: go run hello.go -mode="hello,world" -num=10
命令行中,可以是 --num=10
但不能是 --num==10
。
2. 数据结构和函数
2.1 type Flag
type Flag struct {Name string // flag在命令行中的名字Usage string // 帮助信息Value Value // 要设置的值DefValue string // 默认值(文本格式),用于使用信息
}
Flag
类型代表一条 flag
的状态。
2.2 type FlagSet
type FlagSet struct {// Usage函数在解析flag出现错误时会被调用// 该字段为一个函数(而非采用方法),以便修改为自定义的错误处理函数Usage func()// 内含隐藏或非导出字段
}
FlagSet
代表一个已注册的 flag
的集合。 FlagSet
零值没有名字,采用 ContinueOnError
错误处理策略。
在 flag
包中,进行了进一步封装:将 FlagSet
的方法都重新定义了一遍,也就是提供了一序列函数,而函数中只是简单的调用已经实例化好了的 FlagSet
。
所以我们只需要关注 flag
中的函数即可,它会自动调用 FlagSet
中的函数。
2.3 func NFlag
func NFlag() int
NFlag
返回已被设置的 flag
的数量。
2.4 func Lookup
func Lookup(name string) *Flag
返回已经已注册 flag
的 Flag
结构体指针;如果 flag
不存在的话,返回 nil
。
2.5 func NArg
func NArg() int
NArg
返回解析 flag
之后剩余参数的个数。
2.6 func Args
func Args() []string
返回解析之后剩下的非 flag
参数。(不包括命令名)也就是说无法进行flag匹配的有哪些参数。
2.7 func Arg
func Arg(i int) string
返回解析之后剩下的第 i
个参数,从 0 开始索引。
2.8 func PrintDefaults
func PrintDefaults()
PrintDefault
会向标准错误输出写入所有注册好的 flag
的默认值。
2.9 func Bool
func Bool(name string, value bool, usage string) *bool
Bool
用指定的名称、默认值、使用信息注册一个 bool
类型 flag
。返回一个保存了该 flag
的值的指针。
2.10 func BoolVar
func BoolVar(p *bool, name string, value bool, usage string)
BoolVar
用指定的名称、默认值、使用信息注册一个 bool
类型 flag
,并将 flag
的值保存到 p
指向的变量。
2.11 func Int
func Int(name string, value int, usage string) *int
Int
用指定的名称、默认值、使用信息注册一个 int
类型 flag
。返回一个保存了该 flag
的值的指针。
2.12 func IntVar
func IntVar(p *int, name string, value int, usage string)
IntVar
用指定的名称、默认值、使用信息注册一个 int
类型 flag
,并将 flag
的值保存到 p
指向的变量。
2.13 func Int64
func Int64(name string, value int64, usage string) *int64
Int64
用指定的名称、默认值、使用信息注册一个 int64
类型 flag
。返回一个保存了该 flag
的值的指针。
2.14 func Int64Var
func Int64Var(p *int64, name string, value int64, usage string)
Int64Var
用指定的名称、默认值、使用信息注册一个 int64
类型 flag
,并将 flag
的值保存到 p
指向的变量。
2.15 func Uint
func Uint(name string, value uint, usage string) *uint
Uint
用指定的名称、默认值、使用信息注册一个 uint
类型 flag
。返回一个保存了该 flag
的值的指针。
2.16 func UintVar
func UintVar(p *uint, name string, value uint, usage string)
UintVar
用指定的名称、默认值、使用信息注册一个 uint
类型 flag
,并将 flag
的值保存到 p
指向的变量。
2.17 func Uint64
func Uint64(name string, value uint64, usage string) *uint64
Uint64
用指定的名称、默认值、使用信息注册一个 uint64
类型 flag
。返回一个保存了该 flag
的值的指针。
2.18 func Uint64Var
func Uint64Var(p *uint64, name string, value uint64, usage string)
Uint64Var
用指定的名称、默认值、使用信息注册一个 uint64
类型 flag
,并将 flag
的值保存到 p
指向的变量。
2.19 func Float64
func Float64(name string, value float64, usage string) *float64
Float64
用指定的名称、默认值、使用信息注册一个 float64
类型 flag
。返回一个保存了该 flag
的值的指针。
2.20 func Float64Var
func Float64Var(p *float64, name string, value float64, usage string)
Float64Var
用指定的名称、默认值、使用信息注册一个 float64
类型 flag
,并将 flag
的值保存到 p
指向的变量。
2.21 func String
func String(name string, value string, usage string) *string
String
用指定的名称、默认值、使用信息注册一个 string
类型 flag
。返回一个保存了该 flag
的值的指针。
2.22 func StringVar
func StringVar(p *string, name string, value string, usage string)
StringVar
用指定的名称、默认值、使用信息注册一个 string
类型 flag
,并将 flag
的值保存到 p
指向的变量。
2.23 func Duration
func Duration(name string, value time.Duration, usage string) *time.Duration
Duration
用指定的名称、默认值、使用信息注册一个 time.Duration
类型 flag
。返回一个保存了该 flag
的值的指针。
2.24 func DurationVar
func DurationVar(p *time.Duration, name string, value time.Duration, usage string)
DurationVar
用指定的名称、默认值、使用信息注册一个 time.Duration
类型 flag
,并将 flag
的值保存到 p
指向的变量。
2.25 func Var
func Var(value Value, name string, usage string)
Var
方法使用指定的名字、使用信息注册一个 flag
。该 flag
的类型和值由第一个参数表示,该参数应实现了 Value
接口。例如,用户可以创建一个 flag
,可以用 Value
接口的 Set
方法将逗号分隔的字符串转化为字符串切片。
2.26 func Set
func Set(name, value string) error
设置已注册的 flag
的值。
2.27 func Parse
func Parse()
从 os.Args[1:]
中解析注册的 flag
。必须在所有 flag
都注册好而未访问其值时执行。未注册却使用 flag -help
时,会返回 ErrHelp
。
2.28 func Parsed
func Parsed() bool
返回是否 Parse
已经被调用过。
2.29 func Visit
func Visit(fn func(*Flag))
按照字典顺序遍历标签,并且对每个标签调用 fn
。 这个函数只遍历解析时进行了设置的标签。
2.30 func VisitAll
func VisitAll(fn func(*Flag))
按照字典顺序遍历标签,并且对每个标签调用 fn
。 这个函数会遍历所有标签,不管解析时有无进行设置。
3. 代码示例
3.1 解析 flag 参数为指针
package mainimport ("flag""fmt"
)// 定义命令行参数
var mode = flag.String("mode", "", "process mode")
var num = flag.Int("num", 5, "process number")
var isProcess = flag.Bool("isProcess", true, "process bool")func main() {// 未解析时查看已设置的 flag 数量registerNum := flag.NFlag()fmt.Printf("Before Parse registerNum is %#v\n", registerNum)// Before Parse registerNum is 0// 解析命令行参数flag.Parse()registerNum = flag.NFlag()fmt.Printf("After Parse registerNum is %#v\n", registerNum)// After Parse registerNum is 3// 无法进行flag匹配的有哪些参数flagArgs := flag.Args()fmt.Printf("flagArgs is %#v\n", flagArgs)// 输出命令行参数fmt.Println(*mode) // 必须加 * 号fmt.Println(*num)fmt.Println(*isProcess)
}
运行结果:
wohu@wohu:~/GoCode/src/task$ go run main.go --mode "hello" --num 10 --isProcess=0
Before Parse registerNum is 0
After Parse registerNum is 3
flagArgs is []string{}
hello
10
false
wohu@wohu:~/GoCode/src/task$ ^C
3.2 解析 flag 参数为变量
package mainimport ("flag""fmt"
)func main() {// 定义命令行参数var mode stringvar num intvar isProcess bool// flag.StringVar这样的函数第一个参数换成了变量地址,后面的参数和flag.String是一样的flag.StringVar(&mode, "mode", "", "process mode")flag.IntVar(&num, "num", 5, "process number")flag.BoolVar(&isProcess, "isProcess", true, "process bool")// 解析命令行参数flag.Parse()// 输出命令行参数fmt.Println("mode is ", mode)fmt.Println("num is ", num)fmt.Println("isProcess is ", isProcess)
}
flag.StringVar
和 flag.String
的区别:
flag.StringVar
函数第一个参数为变量地址,该变量需要提前声明,其余参数和flag.String
是一样的;flag.StringVar
第一个参数就是变量的实际值,可以直接使用,而flag.String
返回的是一个指针地址,使用的时候需要加 * 标记;
其它 flag.xxx
和 flag.xxxVar
的区别和上面所说的一样。
3.3 自定义 flag 参数
使用 flag.var()
可以把自定义的数据类型作为参数值的类型,核心在于自定义的数据类型需要实现Value
接口。
package mainimport ("errors""flag""fmt""strconv""strings"
)type Student struct {Name stringAge int
}func (s *Student) String() string {return fmt.Sprintf("Name: %s, Age: %d\n", s.Name, s.Age)
}func (s *Student) Set(_s string) error {studentArr := strings.Split(_s, ",")if len(studentArr) == 2 {s.Name = studentArr[0]s.Age, _ = strconv.Atoi(studentArr[1])return nil}return errors.New("error")
}func main() {name := flag.String("name", "admin", "user name")s := new(Student)flag.Var(s, "student", "student info")flag.Parse()fmt.Println("hello,", *name)fmt.Println(s)
}
执行结果:
wohu@wohu:~/GoCode/src$ go run demo.go -name "wohu" -student "wohu",20
hello, wohu
Name: wohu, Age: 20wohu@wohu:~/GoCode/src$
Go 学习笔记(45)— Go 标准库之 flag(命令行参数解析)相关推荐
- GO标准库—命令行参数解析FLAG
评论有人提到没有例子,不知道讲的是什么.因此,为了大家能够更好地理解,特意加了一个示例.其实本文更多讲解的是 flag 的实现原理,加上示例之后,就更好地知道怎么使用了.建议阅读 <Go语言标准 ...
- Python学习笔记: Python 标准库概览
本文来自:入门指南 开胃菜参考:开胃菜 使用Python解释器:使用Python解释器 本文对Python的简介:Python 简介 Python流程介绍:深入Python 流程 Python数据结构 ...
- boost学习之命令行参数解析库program_options
介绍 程序参数项(program options)是一系列name=value对,program_options 允许程序开发者获得通过命令行(command line)和配置文件(config fi ...
- python基础教程_学习笔记14:标准库:一些最爱——re
标准库:一些最爱 re re模块包括对正則表達式的支持,由于以前系统学习过正則表達式,所以基础内容略过,直接看python对于正則表達式的支持. 正則表達式的学习,见<Mastering Reg ...
- python基础课程_学习笔记13:标准库:有些收藏夹——sys
标准库:有些收藏夹 sys sys这个模块可以让你访问和python解释器联系紧密的变量和函数. sys模块中一些重要的函数和变量 函数/变量 描写叙述 argv 命令行參数,包含脚本名称 exit( ...
- Python学习笔记: Python 标准库概览二
本文来自:入门指南 开胃菜参考:开胃菜 使用Python解释器:使用Python解释器 本文对Python的简介:Python 简介 Python流程介绍:深入Python 流程 Python数据结构 ...
- 命令行参数tail c语言,osg学习笔记2, 命令行参数解析器ArgumentParser
php简单实现socket通信 socket通信的原理在这里就不说了,它的用途还是比较广泛的,我们可以使用socket来做一个API接口出来,也可以使用socket来实现两个程序之间的通信,我们来研究 ...
- Python学习笔记17:标准库之数学相关(math包,random包)
前面几节看得真心累.如今先来点简单easy理解的内容. 一 math包 math包主要处理数学相关的运算. 常数 math.e # 自然常数e math.pi # 圆周率pi 运算函数 math ...
- Python学习笔记14:标准库之信号量(signal包)
signal包负责在Python程序内部处理信号.典型的操作包含预设信号处理函数,暂停并等待信号,以及定时发出SIGALRM等. 要注意,signal包主要是针对UNIX平台(比方Linux, MAC ...
最新文章
- 初识Service Worker
- python制作贪吃蛇游戏_用Python写贪吃蛇游戏的代码实例
- 【Android 异步操作】FutureTask 分析 ( Future 接口解析 | Runnable 接口解析 | Callable 接口解析 )
- Python小白学习之函数装饰器
- 【音频处理】离散傅里叶变换
- 一步一步学Remoting系列文章
- Python 数据分析三剑客之 NumPy(四):字符串函数总结与对比
- VIO Estimator::processIMU 函数
- oracle 触发器 insert 前检查_一文看懂INSTEAD OF 与AFTER 触发器区别与联系
- 06_LR和最大熵模型_统计学习方法
- Kotlin — 心印(熟悉与锻炼Kotlin语法)
- 【详细】遍历Windows文件
- 1. jQuery 简介
- Remoting PerfMon Service
- 一个关于Booth算法的文章
- 为什么计算机软件比一般作品较多,插画-从入门到进阶的小心得
- 应届生产品助理/经理面试,应当多谈点什么?
- canvas漫天闪烁的星星
- 传输预编码matlab,基于MATLAB的MIMO系统预编码性能仿真.doc
- 2017最新qq第三方登陆教程